2 ###################################################
3 # InspIRCd Configuration Script
5 # Copyright 2002-2007 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_nick_length,
101 $opt_chan_length, $opt_maxclients, $opt_ports, $opt_epoll, $opt_kqueue, $opt_noports,
102 $opt_noepoll, $opt_nokqueue, $opt_disablerpath, $opt_ipv6, $opt_ipv6links,
103 $opt_noipv6links, $opt_ident, $opt_quit, $opt_topic, $opt_maxbuf, $opt_kick,
104 $opt_gecos, $opt_away, $opt_modes, $opt_disable_debug, $opt_maxchans,
107 our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir,
112 sub enable_extras (@);
114 sub disable_extras (@);
116 my @opt_enableextras;
117 my @opt_disableextras;
120 'enable-gnutls' => \$opt_use_gnutls,
121 'rebuild' => \$opt_rebuild,
122 'enable-openssl' => \$opt_use_openssl,
123 'disable-interactive' => \$opt_nointeractive,
124 'with-nick-length=i' => \$opt_nick_length,
125 'with-channel-length=i' => \$opt_chan_length,
126 'with-max-clients=i' => \$opt_maxclients,
127 'enable-ports' => \$opt_ports,
128 'enable-epoll' => \$opt_epoll,
129 'enable-kqueue' => \$opt_kqueue,
130 'disable-ports' => \$opt_noports,
131 'disable-epoll' => \$opt_noepoll,
132 'disable-kqueue' => \$opt_nokqueue,
133 'disable-rpath' => \$opt_disablerpath,
134 'enable-ipv6' => \$opt_ipv6,
135 'enable-remote-ipv6' => \$opt_ipv6links,
136 'disable-remote-ipv6' => \$opt_noipv6links,
137 'with-cc=s' => \$opt_cc,
138 'with-ident-length=i' => \$opt_ident,
139 'with-quit-length=i' => \$opt_quit,
140 'with-topic-length=i' => \$opt_topic,
141 'with-maxbuf=i' => \$opt_maxbuf,
142 'with-kick-length=i' => \$opt_kick,
143 'with-gecos-length=i' => \$opt_gecos,
144 'with-away-length=i' => \$opt_away,
145 'with-max-modes=i' => \$opt_modes,
146 'prefix=s' => \$opt_base_dir,
147 'config-dir=s' => \$opt_config_dir,
148 'module-dir=s' => \$opt_module_dir,
149 'binary-dir=s' => \$opt_binary_dir,
150 'library-dir=s' => \$opt_library_dir,
151 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
152 'help' => sub { showhelp(); },
153 'modupdate' => sub { modupdate(); },
154 'update' => sub { update(); },
155 'svnupdate' => sub { svnupdate(); },
156 'clean' => sub { clean(); },
157 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
158 'enable-extras=s@' => \@opt_enableextras, # ^
159 'disable-extras=s@' => \@opt_disableextras, # ^
162 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
163 @opt_enableextras = split /,/, join(',', @opt_enableextras);
164 @opt_disableextras = split /,/, join(',', @opt_disableextras);
165 enable_extras(@opt_enableextras);
166 disable_extras(@opt_disableextras);
168 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
169 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
173 our $non_interactive = (
174 (defined $opt_library_dir) ||
175 (defined $opt_base_dir) ||
176 (defined $opt_config_dir) ||
177 (defined $opt_module_dir) ||
178 (defined $opt_base_dir) ||
179 (defined $opt_binary_dir) ||
180 (defined $opt_nointeractive) ||
181 (defined $opt_away) ||
182 (defined $opt_gecos) ||
183 (defined $opt_kick) ||
184 (defined $opt_maxclients) ||
185 (defined $opt_modes) ||
186 (defined $opt_topic) ||
187 (defined $opt_quit) ||
188 (defined $opt_ident) ||
190 (defined $opt_ipv6) ||
191 (defined $opt_ipv6links) ||
192 (defined $opt_noipv6links) ||
193 (defined $opt_kqueue) ||
194 (defined $opt_epoll) ||
195 (defined $opt_ports) ||
196 (defined $opt_maxchans) ||
197 (defined $opt_opermaxchans) ||
198 (defined $opt_chan_length) ||
199 (defined $opt_nick_length) ||
200 (defined $opt_use_openssl) ||
201 (defined $opt_nokqueue) ||
202 (defined $opt_noepoll) ||
203 (defined $opt_noports) ||
204 (defined $opt_maxbuf) ||
205 (defined $opt_use_gnutls)
207 our $interactive = !$non_interactive;
209 chomp(our $topdir = getcwd());
210 our $this = resolve_directory($topdir); # PWD, Regardless.
211 our @modlist = (); # Declare for Module List..
212 our %config = (); # Initiate Configuration Hash..
213 $config{ME} = resolve_directory($topdir); # Present Working Directory
215 $config{BASE_DIR} = $config{ME};
217 if (defined $opt_base_dir)
219 $config{BASE_DIR} = $opt_base_dir;
222 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
223 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
224 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
225 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
227 if (defined $opt_config_dir)
229 $config{CONFIG_DIR} = $opt_config_dir;
231 if (defined $opt_module_dir)
233 $config{MODULE_DIR} = $opt_module_dir;
235 if (defined $opt_binary_dir)
237 $config{BINARY_DIR} = $opt_binary_dir;
239 if (defined $opt_library_dir)
241 $config{LIBRARY_DIR} = $opt_library_dir;
243 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
244 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version
245 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
246 chomp(our $openssl_ver = $config{HAS_OPENSSL});
247 $config{USE_GNUTLS} = "n";
248 if (defined $opt_use_gnutls)
250 $config{USE_GNUTLS} = "y"; # Use gnutls.
252 $config{USE_OPENSSL} = "n"; # Use openssl.
253 if (defined $opt_use_openssl)
255 $config{USE_OPENSSL} = "y";
258 # no, let's not change these.
259 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
260 if (!defined $opt_disable_debug)
262 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
266 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
269 $config{NICK_LENGT} = "31"; # Default Nick Length
270 if (defined $opt_nick_length)
272 $config{NICK_LENGT} = $opt_nick_length;
274 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
275 if (defined $opt_chan_length)
277 $config{CHAN_LENGT} = $opt_chan_length;
279 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
280 if (defined $opt_modes)
282 $config{MAXI_MODES} = $opt_modes;
284 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
285 $config{HAS_STDINT} = "false"; # stdint.h check
286 $config{USE_KQUEUE} = "y"; # kqueue enabled
287 if (defined $opt_kqueue)
289 $config{USE_KQUEUE} = "y";
291 if (defined $opt_nokqueue)
293 $config{USE_KQUEUE} = "n";
295 $config{USE_EPOLL} = "y"; # epoll enabled
296 if (defined $opt_epoll)
298 $config{USE_EPOLL} = "y";
300 if (defined $opt_noepoll)
302 $config{USE_EPOLL} = "n";
304 $config{USE_PORTS} = "y"; # epoll enabled
305 if (defined $opt_ports)
307 $config{USE_PORTS} = "y";
309 if (defined $opt_noports)
311 $config{USE_PORTS} = "n";
313 $config{IPV6} = "n"; # IPv6 support (experimental)
314 if (defined $opt_ipv6)
318 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
319 if (defined $opt_ipv6links)
321 $config{SUPPORT_IP6LINKS} = "y";
323 if (defined $opt_noipv6links)
325 $config{SUPPORT_IP6LINKS} = "n";
327 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit
328 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`); # Hard FD Limit
329 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
330 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
331 $config{OSNAME} = $^O; # Operating System Name
332 $config{IS_DARWIN} = "NO"; # Is OSX?
333 $config{STARTSCRIPT} = "inspircd"; # start script?
334 $config{DESTINATION} = "BASE"; # Is target path.
335 $config{EXTRA_DIR} = ""; # Is empty.
336 if ($config{OSNAME} =~ /darwin/i)
338 $config{IS_DARWIN} = "YES";
339 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
340 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
341 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
343 $config{CC} = "g++"; # C++ compiler
346 $config{CC} = $opt_cc;
348 our $exec = $config{CC} . " -dumpversion | cut -c 1";
349 chomp($config{GCCVER} = `$exec`); # Major GCC Version
350 $config{MAKEORDER} = "ircd mods"; # build order
351 $config{MAX_IDENT} = "12"; # max ident size
352 $config{MAX_QUIT} = "255"; # max quit message size
353 $config{MAX_TOPIC} = "307"; # max topic size
354 $config{MAX_KICK} = "255"; # max kick message size
355 $config{MAX_GECOS} = "128"; # max GECOS size
356 $config{MAX_AWAY} = "200"; # max AWAY size
357 $config{MAXBUF} = "512"; # Max buffer size
358 if (defined $opt_ident)
360 $config{MAX_IDENT} = $opt_ident;
362 if (defined $opt_quit)
364 $config{MAX_QUIT} = $opt_quit;
366 if (defined $opt_topic)
368 $config{MAX_TOPIC} = $opt_topic;
370 if (defined $opt_kick)
372 $config{MAX_KICK} = $opt_kick;
374 if (defined $opt_gecos)
376 $config{MAX_GECOS} = $opt_gecos;
378 if (defined $opt_away)
380 $config{MAX_AWAY} = $opt_away;
383 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
384 $config{HAS_OPENSSL} = $1;
386 $config{HAS_OPENSSL} = "";
389 if ($config{GCCVER} eq "") {
390 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
394 our $fd_scan_fail = "";
395 if (!$config{MAX_CLIENT_T}) {
396 $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default'
397 $fd_scan_fail = "true"; # Used Later
400 # Get and Set some important vars..
405 unlink(".config.cache");
408 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
413 chomp($topdir = getcwd());
414 $this = resolve_directory($topdir); # PWD, Regardless.
416 # Does the cache file exist?
418 # No, No it doesn't.. *BASH*
419 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
422 # We've Loaded the cache file and all our variables..
423 print "Updating files...\n";
425 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
427 print "Disabling debug information (-g).\n";
428 $config{OPTIMISATI} = "";
431 $has_epoll = $config{HAS_EPOLL};
432 $has_ports = $config{HAS_PORTS};
433 $has_kqueue = $config{HAS_KQUEUE};
442 print "Configure update failed: $@\n";
450 chomp($topdir = getcwd());
451 $this = resolve_directory($topdir); # PWD, Regardless.
453 # Does the cache file exist?
455 # No, No it doesn't.. *BASH*
456 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
459 # We've Loaded the cache file and all our variables..
460 print "Updating files...\n";
462 $has_epoll = $config{HAS_EPOLL};
463 $has_ports = $config{HAS_PORTS};
464 $has_kqueue = $config{HAS_KQUEUE};
473 print "Module update failed: $@\n";
483 open(FH,"<.svn/entries") or $fail = 1;
485 print "This is not an SVN copy of InspIRCd.\n";
492 system("svn update");
493 system("perl configure -update");
494 if (defined $opt_rebuild) {
495 system("make install");
500 print "Running non-interactive configure...\n" unless $interactive;
501 print "Checking for cache from previous configure... ";
502 print ((!getcache()) ? "not found\n" : "found\n");
503 print "Checking operating system version... ";
504 print getosflags() . "\n";
506 if (defined $opt_maxclients)
508 $config{MAX_CLIENT} = $opt_maxclients;
511 if (!$config{MAX_CLIENT}) {
512 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
513 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
514 # higher than the found value" :))
515 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
518 printf "Checking if stdint.h exists... ";
519 $config{HAS_STDINT} = "true";
521 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
522 if ($config{HAS_STDINT} eq "true") {
525 print "yes\n" if $config{HAS_STDINT} eq "true";
526 print "no\n" if $config{HAS_STDINT} eq "false";
528 printf "Checking if strlcpy exists... ";
529 # Perform the strlcpy() test..
530 $config{HAS_STRLCPY} = "false";
532 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
534 while (defined(my $line = <STRLCPY>)) {
536 # try and find the delcaration of:
537 # size_t strlcpy(...)
538 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
539 $config{HAS_STRLCPY} = "true";
544 print "yes\n" if $config{HAS_STRLCPY} eq "true";
545 print "no\n" if $config{HAS_STRLCPY} eq "false";
547 printf "Checking if kqueue exists... ";
550 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
552 while (defined(my $line = <KQUEUE>)) {
554 # try and find the delcaration of:
556 if ($line =~ /int(\0x9|\s)+kqueue/) {
562 print "yes\n" if $has_kqueue == 1;
563 print "no\n" if $has_kqueue == 0;
565 printf "Checking if epoll exists... ";
568 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
574 my $kernel = `uname -r`;
576 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
581 # Suggestion from nenolod, weed out odd systems which have glibc built
582 # against 2.4 kernels (ick)
583 my $kernel_arch = `uname -p`;
587 if ($kernel_arch =~ /x86_64/) {
588 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
591 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
595 while (defined(my $line = <FH>))
598 if ($line =~ /GNU C Library .* version (.*?) /)
601 $libcv =~ /(\d+\.\d+)/;
604 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
607 # Fix for some retarded libc builds, strip off >> and << etc.
608 $kernelv =~ /(\d+\.\d+)/;
616 printf "libc too old: $libcv... ";
621 printf "libc built against older kernel $kernelv... ";
626 print "yes\n" if $has_epoll == 1;
627 print "no\n" if $has_epoll == 0;
629 printf "Checking if Solaris I/O completion ports are available... ";
631 our $system = `uname -s`;
633 $has_ports = 1 if ($system eq "SunOS");
636 my $kernel = `uname -r`;
638 if (($kernel !~ /^5\.1./)) {
642 print "yes\n" if $has_ports == 1;
643 print "no\n" if $has_ports == 0;
645 $config{HAS_EPOLL} = $has_epoll;
646 $config{HAS_KQUEUE} = $has_kqueue;
648 printf "Checking for libgnutls... ";
649 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
651 $config{HAS_GNUTLS} = "y";
654 $config{HAS_GNUTLS} = "n";
657 printf "Checking for openssl... ";
658 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
660 $config{HAS_OPENSSL} = "y";
663 $config{HAS_OPENSSL} = "n";
666 printf "Checking if you are running an ancient, unsupported OS... ";
667 if ($config{OSNAME} =~ /FreeBSD/i)
669 my $version = `uname -r`;
670 if ($version =~ /^4\./)
672 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
675 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
676 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
681 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
687 print "no ($version)\n";
693 print "no ($config{OSNAME})\n";
696 ################################################################################
697 # BEGIN INTERACTIVE PART #
698 ################################################################################
703 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
706 my $rev = getrevision();
707 # Display Introduction Message..
709 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
710 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
712 *** If you are unsure of any of these values, leave it blank for ***
713 *** standard settings that will work, and your server will run ***
714 *** using them. Please consult your IRC network admin if in doubt. ***
716 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
717 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
718 dir, otherwise you won't have a config file!
720 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
721 Maximum file descriptors: \e[1;32m$config{MAX_CLIENT_T}\e[0m
722 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
725 print " (Non-SVN build)";
729 $config{CHANGE_COMPILER} = "n";
730 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
732 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
733 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
734 should NOT be used. You should probably specify a newer compiler.\n\n";
735 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
736 if ($config{CHANGE_COMPILER} =~ /y/i) {
737 print "What command do you want to use to invoke your compiler?\n";
738 print "[\e[1;32m$config{CC}\e[0m] -> ";
739 chomp($config{CC} = <STDIN>);
740 if ($config{CC} eq "") {
743 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
745 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
746 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
747 if ($config{GCCVER} < 3) {
748 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
752 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
759 # Directory Settings..
760 my $tmpbase = $config{BASE_DIR};
761 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
762 if ($tmpbase ne $config{BASE_DIR}) {
763 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
764 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
765 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
766 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
769 dir_check("are the configuration files", "CONFIG_DIR");
770 dir_check("are the modules to be compiled to", "MODULE_DIR");
771 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
772 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
775 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?");
779 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?");
783 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?");
786 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
787 if (!$chose_hiperf) {
788 print "No high-performance socket engines are available, or you chose\n";
789 print "not to enable one. Defaulting to select() engine.\n\n";
792 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
795 if ($config{IPV6} eq "y") {
796 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";
797 $config{SUPPORT_IP6LINKS} = "y";
799 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?\nIf you are using a recent operating\nsystem and are unsure, answer yes.\nIf you answer 'no' here, your InspIRCd server will be unable\nto parse IPV6 addresses (e.g. for CIDR bans)");
803 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
804 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
805 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
806 print "instead, you should enable the OpenSSL module yourself\n";
807 print "by copying it from src/modules/extra to src/modules.\n\n";
808 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
809 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
812 if ($config{HAS_GNUTLS} eq "y") {
813 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
814 if ($config{USE_GNUTLS} eq "y") {
815 print "\nUsing GnuTLS SSL module.\n";
817 } elsif ($config{HAS_OPENSSL} eq "y") {
818 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
819 if ($config{USE_OPENSSL} eq "y") {
820 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
824 print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\nyou intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n";
827 print "\nThe following questions will ask you for various figures relating\n";
828 print "To your IRCd install. Please note that these should usually be left\n";
829 print "as defaults unless you have a real reason to change them. If they\n";
830 print "changed, then the values must be identical on all servers on your\n";
831 print "network, or malfunctions and/or crashes may occur, with the exception\n";
832 print "of the 'maximum number of clients' setting which may be different on\n";
833 print "different servers on the network.\n\n";
835 # File Descriptor Settings..
836 promptnumeric("number of clients at any one time", "MAX_CLIENT_T");
837 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
838 $config{MAX_DESCRIPTORS} = $config{MAX_CLIENT_T};
840 promptnumeric("length of nicknames", "NICK_LENGT");
841 promptnumeric("length of channel names", "CHAN_LENGT");
842 promptnumeric("number of mode changes in one line", "MAXI_MODES");
843 promptnumeric("length of an ident (username)", "MAX_IDENT");
844 promptnumeric("length of a quit message", "MAX_QUIT");
845 promptnumeric("length of a channel topic", "MAX_TOPIC");
846 promptnumeric("length of a kick message", "MAX_KICK");
847 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
848 promptnumeric("length of an away message", "MAX_AWAY");
853 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
855 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
858 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
860 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
865 if ($config{USE_GNUTLS} eq "y") {
866 unless (-r "src/modules/m_ssl_gnutls.cpp") {
867 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
868 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
873 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
874 print "SSL Certificates Not found, Generating.. \n\n
875 *************************************************************
876 * Generating the Private Key may take some time, go grab a *
877 * Coffee. Even better, to generate some more entropy if it *
878 * is taking a while, open another console and type du / a *
879 * few times and get that HD going :) Then answer the *
880 * Questions which follow. If you are unsure, just hit enter *
881 *************************************************************\n\n";
882 $failed = make_gnutls_cert();
884 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
886 print "\nCertificate generation complete, copying to config directory... ";
887 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
888 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
893 print "SSL Certificates found, skipping.\n\n";
898 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
900 } elsif ($config{USE_OPENSSL} eq "y") {
901 unless (-r "src/modules/m_ssl_openssl.cpp") {
902 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
903 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
909 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
910 print "SSL Certificates Not found, Generating.. \n\n
911 *************************************************************
912 * Generating the certificates may take some time, go grab a *
913 * coffee, or something. *
914 *************************************************************\n\n";
916 print "\nCertificate generation complete, copying to config directory... ";
917 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
918 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
919 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
922 print "SSL Certificates found, skipping.\n\n"
927 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
930 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
931 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
939 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
940 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
941 print "Please remember that to enable \e[1;32mSSL support\e[0m you must\n";
942 print "load the required modules in your config. This configure process\n";
943 print "has just prepared these modules to be compiled for you, and has not\n";
944 print "configured them to be compiled into the core of the ircd.\n";
946 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
947 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
948 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";
951 if ($config{GCCVER} < "3") {
953 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
954 GCC 2.x series compilers only had partial (read as broken) C++ support, and
955 your compile will most likely fail horribly! If you have any problems, do NOT
956 report them to the bugtracker or forums without first upgrading your compiler
957 to a newer 3.x or 4.x (or whatever is available currently) version.
961 ################################################################################
963 ################################################################################
965 # Retrieves the .config.cache file, and loads values into the main config hash.
966 open(CACHE, ".config.cache") or return 0;
969 # Ignore Blank lines, and comments..
972 my ($key, $value) = split("=", $_, 2);
973 $value =~ /^\"(.*)\"$/;
974 # Do something with data here!
982 # Dump the contents of %config
983 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
984 open(FILEHANDLE, ">.config.cache");
985 foreach my $key (keys %config) {
986 print FILEHANDLE "$key=\"$config{$key}\"\n";
992 my ($desc, $hash_key) = @_;
995 print "In what directory $desc?\n";
996 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
997 chomp(my $var = <STDIN>);
999 $var = $config{$hash_key};
1001 if ($var =~ /^\~\/(.+)$/) {
1002 # Convert it to a full path..
1003 $var = resolve_directory($ENV{HOME} . "/" . $1);
1005 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1007 # Assume relative Path was given.. fill in the rest.
1008 $var = $this . "/$var";
1011 $var = resolve_directory($var);
1013 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1014 chomp(my $tmp = <STDIN>);
1015 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1016 # Attempt to Create the Dir..
1019 File::Path::mkpath($var, 0, 0777);
1022 unless (defined($chk) && -d $var) {
1023 print "Unable to create directory. ($var)\n\n";
1028 # They said they don't want to create, and we can't install there.
1033 if (!is_dir($var)) {
1034 # Target exists, but is not a directory.
1035 print "File $var exists, but is not a directory.\n\n";
1039 # Either Dir Exists, or was created fine.
1040 $config{$hash_key} = $var;
1050 # Beware: Linux sets it's own cflags below for some retarded reason
1051 $config{LDLIBS} = "-pthread -lstdc++";
1052 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1053 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -g";
1054 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1055 $config{MAKEPROG} = "make";
1057 if ($config{OSNAME} =~ /darwin/i) {
1058 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1059 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1060 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1063 if ($config{OSNAME} =~ /OpenBSD/i) {
1064 $config{MAKEPROG} = "gmake";
1065 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1066 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1067 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1068 # if theyre not running this, configure lets the build continue but they probably wont manage to
1069 # compile as this standard version is 2.95.3!
1071 $config{CC} = "eg++";
1072 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1077 if ($config{OSNAME} =~ /Linux/i) {
1078 $config{LDLIBS} = "-ldl -lstdc++ -pthread";
1079 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wall $config{OPTIMISATI}";
1080 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1081 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1082 $config{MAKEPROG} = "make";
1085 if ($config{OSNAME} =~ /FreeBSD/i) {
1086 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1087 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1090 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1092 # solaris/sunos needs these
1093 # socket = bsd sockets api
1095 # rt = POSIX realtime extensions
1096 # resolv = inet_aton only (why isnt this in nsl?!)
1097 $config{MAKEPROG} = "gmake";
1098 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv -pthread";
1102 if($config{OSNAME} =~ /MINGW32/i)
1104 # All code is position-independent on windows
1105 $config{FLAGS} =~ s/-fPIC //;
1109 return $config{OSNAME};
1112 my ($mliflags, $mfrules, $mobjs, $mfcount) = ("", "", "", 0);
1115 my($writeheader) = @_;
1117 # First File.. inspircd_config.h
1118 chomp(my $incos = `uname -n -s -r`);
1119 chomp(my $version = `sh src/version.sh`);
1120 chomp(my $revision2 = getrevision());
1121 if ($writeheader == 1)
1123 print "Writing \e[1;32minspircd_config.h\e[0m\n";
1124 open(FILEHANDLE, ">include/inspircd_config.h");
1125 my $NL = $config{NICK_LENGT}+1;
1126 my $CL = $config{CHAN_LENGT}+1;
1127 print FILEHANDLE <<EOF;
1128 /* Auto generated by configure, do not modify! */
1129 #ifndef __CONFIGURATION_AUTO__
1130 #define __CONFIGURATION_AUTO__
1132 /* this is for windows support. */
1133 #define CoreExport /**/
1134 #define DllExport /**/
1136 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1137 #define MOD_PATH "$config{MODULE_DIR}"
1138 #define VERSION "$version"
1139 #define REVISION "$revision2"
1140 #define MAXCLIENTS $config{MAX_CLIENT}
1141 #define MAXCLIENTS_S "$config{MAX_CLIENT}"
1142 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1143 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1146 #define MAXMODES $config{MAXI_MODES}
1147 #define IDENTMAX $config{MAX_IDENT}
1148 #define MAXQUIT $config{MAX_QUIT}
1149 #define MAXTOPIC $config{MAX_TOPIC}
1150 #define MAXKICK $config{MAX_KICK}
1151 #define MAXGECOS $config{MAX_GECOS}
1152 #define MAXAWAY $config{MAX_AWAY}
1153 #define OPTIMISATION $config{OPTIMITEMP}
1154 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1155 #define SYSTEM "$incos"
1157 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1159 if ($config{OSNAME} =~ /SunOS/i) {
1160 print FILEHANDLE "#define IS_SOLARIS\n";
1162 if ($config{OSNAME} =~ /MINGW32/i) {
1163 print FILEHANDLE "#define IS_MINGW\n";
1165 if ($config{GCCVER} >= 3) {
1166 print FILEHANDLE "#define GCC3\n";
1168 if ($config{HAS_STRLCPY} eq "true") {
1169 print FILEHANDLE "#define HAS_STRLCPY\n";
1171 if ($config{HAS_STDINT} eq "true") {
1172 print FILEHANDLE "#define HAS_STDINT\n";
1174 if ($config{IPV6} =~ /y/i) {
1175 print FILEHANDLE "#define IPV6\n";
1177 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1178 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1181 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1182 print FILEHANDLE "#define USE_KQUEUE\n";
1183 $se = "socketengine_kqueue";
1186 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1187 print FILEHANDLE "#define USE_EPOLL\n";
1188 $se = "socketengine_epoll";
1191 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1192 print FILEHANDLE "#define USE_PORTS\n";
1193 $se = "socketengine_ports";
1196 # user didn't choose either epoll or select for their OS.
1197 # default them to USE_SELECT (ewwy puke puke)
1199 print FILEHANDLE "#define USE_SELECT\n";
1200 $se = "socketengine_select";
1202 print FILEHANDLE "\n#endif\n";
1208 open(FILEHANDLE, ">include/inspircd_se_config.h");
1209 print FILEHANDLE <<EOF;
1210 /* Auto generated by configure, do not modify or commit to svn! */
1211 #ifndef __CONFIGURATION_SOCKETENGINE__
1212 #define __CONFIGURATION_SOCKETENGINE__
1214 #include "socketengines/$se.h"
1222 # Create a Modules List..
1224 foreach my $i (@modlist)
1226 $modules .= "m_".$i.".so ";
1228 chomp($modules); # Remove Redundant whitespace..
1230 opendir(DIRHANDLE, "src/modules");
1231 foreach my $name (sort readdir(DIRHANDLE)) {
1232 if ($name =~ /^m_(.+?)$/) {
1233 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1234 closedir(MDIRHANDLE);
1235 $modules .= "$name.so ";
1236 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1240 closedir(DIRHANDLE);
1243 # Write all .in files.
1246 my $exe = "inspircd";
1248 # Do this once here, and cache it in the .*.inc files,
1249 # rather than attempting to read src/version.sh from
1250 # compiled code -- we might not have the source to hand.
1251 # Fix for bug#177 by Brain.
1253 chomp($version = `sh ./src/version.sh`);
1254 chomp(my $revision = getrevision());
1255 $version = "$version(r$revision)";
1257 # We can actually parse any file starting with . and ending with .inc,
1258 # but right now we only parse .inspircd.inc to form './inspircd'
1260 print "Writing \e[1;32mMakefiles\e[0m\n";
1261 write_dynamic_modules_makefile();
1262 write_dynamic_makefile();
1264 opendir(DIRHANDLE, $this);
1266 foreach my $name (sort readdir(DIRHANDLE)) {
1267 if ($name =~ /^\.(.+)\.inc$/) {
1270 # Bug #353, omit this on non-darwin
1271 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1273 # All .name.inc files need parsing!
1275 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1276 while (<FILEHANDLE>) {
1281 print "Writing \e[1;32m$file\e[0m ...\n";
1282 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1283 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1284 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1285 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1286 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1287 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1288 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1289 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1290 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1291 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1292 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1293 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1294 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1295 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1296 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1297 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1298 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1299 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1300 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1302 open(FILEHANDLE, ">$file");
1303 print FILEHANDLE $tmp;
1306 closedir(DIRHANDLE);
1308 # Make inspircd executable!
1309 chmod 0744, 'inspircd';
1312 sub write_dynamic_modules_makefile {
1313 # Modules Makefile..
1314 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1315 open(FILEHANDLE, ">src/modules/Makefile");
1318 # Module Makefile Header
1320 print FILEHANDLE <<EOF;
1321 ###################################################
1322 # Copyright 2002-2007 The InspIRCd Development Team
1323 # http://www.inspircd.org/wiki/index.php/Credits
1325 # Thanks to Andrew Church <achurch\@achurch.org>
1326 # for assisting with making this work right.
1328 # Automatically Generated by ./configure to add a
1329 # modules please run ./configure -modupdate
1330 ###################################################
1336 if ($config{OSNAME} =~ /darwin/) {
1337 print FILEHANDLE <<EOCHEESE;
1339 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1343 print FILEHANDLE <<EOCHEESE;
1345 PICLDFLAGS = -fPIC -DPIC -shared
1351 # End Module Makefile Header
1354 # Create a Modules List..
1358 foreach my $i (@modlist) {
1360 # Write Entry to the MakeFile
1362 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1363 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1364 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1366 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1369 if (nopedantic("src/modules/m_".$i.".cpp"))
1372 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
1373 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1379 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
1380 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1383 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1384 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1386 # End Write Entry to the MakeFile
1390 opendir(DIRHANDLE, "src/modules");
1391 foreach my $name (sort readdir(DIRHANDLE)) {
1392 if ($name =~ /^m_(.+?)$/) {
1397 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1398 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1399 read_module_directory("src/modules/$name", $name);
1400 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1401 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";
1402 if ($config{IS_DARWIN} eq "YES") {
1403 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1405 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1407 print FILEHANDLE "\n$mfrules\n";
1408 closedir(MDIRHANDLE);
1409 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1413 closedir(DIRHANDLE);
1416 sub read_module_directory {
1417 my ($dpath, $reldpath) = @_;
1419 if (opendir(MDIRHANDLE, $dpath) == 0) {
1423 foreach my $fname (sort readdir(MDIRHANDLE)) {
1424 if ($fname =~ /\.cpp$/) {
1425 my $cmflags = getcompilerflags("$dpath/$fname");
1426 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1427 my $deps = getdependencies("$dpath/$fname");
1429 $oname =~ s/\.cpp$/.o/g;
1430 $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";
1431 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1432 $mobjs = $mobjs . " $reldpath/$oname";
1435 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1436 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1443 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1444 # dependencies which are not relevent in C++.
1448 open (CPP, "<$file") or die("Can't open $file for reading!");
1453 foreach my $d (@ignoredeps)
1459 foreach my $dep (@immutabledeps)
1461 $immutable = $immutable . "../include/$dep ";
1463 $immutable =~ s/ $//g;
1465 while (defined(my $line = <CPP>))
1468 if ($line =~ /#include "(.+\.h)"/)
1470 if (!exists($dupe{$1}))
1472 $retlist = $retlist . "../include/$1 ";
1478 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1481 sub write_dynamic_makefile
1485 my %existing_install_list = ();
1486 opendir(DIRHANDLE, "src/commands");
1487 foreach my $name (sort readdir(DIRHANDLE))
1489 if ($name =~ /^cmd_(.+)\.cpp$/)
1491 $cmdlist[$i++] = $1;
1492 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1493 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1496 closedir(DIRHANDLE);
1500 $config{USE_EPOLL} = 0;
1504 $config{USE_KQUEUE} = 0;
1508 $config{USE_PORTS} = 0;
1511 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1513 print "Scanning \e[1;32m$dir\e[0m for core files ";
1514 opendir(DIRHANDLE, $dir);
1515 foreach my $name (sort readdir(DIRHANDLE))
1517 if ($name =~ /\.cpp$/)
1519 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1521 while (defined(my $line = <CPP>))
1524 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1526 $filelist{$name} = $1;
1528 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1530 $specialdeps{$name} = $1;
1532 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1534 $extraobjects{$name} = $1;
1536 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1538 $extrabuildlines{$name} = $1;
1540 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1542 $extrasources{$name} = $1;
1544 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1546 if (defined $config{$1})
1548 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1551 while (defined($line = <CPP>))
1554 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1555 last if ($line =~ /\/\* \$EndIf \*\//i);
1560 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1562 if (!exists($existing_install_list{$1}))
1564 $existing_install_list{$1} = 1;
1565 my $idir = (split(' ',$1))[1];
1566 my $ifile = (split(' ',$1))[0];
1567 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1568 $ifile =~ s/.*\///g;
1569 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1572 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1574 if (!exists($existing_install_list{$1}))
1576 $existing_install_list{$1} = 1;
1577 my $idir = (split(' ',$1))[1];
1578 my $ifile = (split(' ',$1))[0];
1579 $install_list = $install_list . " -cp $1\n";
1580 $ifile =~ s/.*\///g;
1581 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1588 closedir(DIRHANDLE);
1592 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1595 my $all_libsonly = "";
1597 my $libraryext = "";
1601 if ($config{IS_DARWIN} eq "YES")
1603 $libraryext = "dylib";
1604 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp\n \@../make/run-cc.pl \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1609 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1610 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1613 foreach my $cpp (sort keys %filelist)
1615 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1616 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1617 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1618 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1620 $all = $all . "moo inspircd\n";
1622 $othercrap = $othercrap . " $all_libsonly\n\n";
1624 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1627 CC = im a cheezeball
1628 CXXFLAGS = -I../include \${FLAGS}
1629 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1630 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1634 print FH "$all\n\n";
1636 my $deps = calcdeps("src/inspircd.cpp");
1637 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1638 print FH "$othercrap\n";
1640 foreach my $cpp (sort keys %filelist)
1642 my $thislib = $filelist{$cpp} . "." . $libraryext;
1646 $objs =~ s/\.cpp$/.o/;
1647 if (exists($extraobjects{$cpp}))
1649 $objs = $objs . " " . $extraobjects{$cpp};
1651 if (exists($extrasources{$cpp}))
1653 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1655 if ($config{IS_DARWIN} eq "YES")
1657 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1661 if (defined $opt_disablerpath)
1663 $libcrap = " -shared";
1667 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1670 $deps = calcdeps("src/$cpp");
1671 if (exists($extrasources{$cpp}))
1673 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1675 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1678 $deps = $deps . $d . " ";
1682 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1683 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1684 if (exists($extrabuildlines{$cpp}))
1686 print FH " " . $extrabuildlines{$cpp} . "\n";
1688 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1691 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1693 # close main makefile
1697 # generate a list of .so
1698 foreach my $cmd (@cmdlist) {
1699 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1702 # and now reopen the commands makefile
1703 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1706 CXXFLAGS = -I../../include \${FLAGS}
1713 # now print the command file details.
1714 foreach my $cmd (@cmdlist) {
1716 cmd_$cmd.so: cmd_$cmd.cpp ../../include/base.h ../../include/modules.h ../../include/inspircd.h ../../include/channels.h ../../include/users.h ../../include/globals.h ../../include/inspircd_config.h ../../include/commands/cmd_$cmd.h
1717 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1718 \@../../make/run-cc.pl \$(CC) -pipe $SHARED -o cmd_$cmd.so cmd_$cmd.o
1722 #try build a .so, no intermediate .o
1723 # @../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so
1725 #this works for sure
1726 # @../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1727 # @../../make/run-cc.pl \$(CC) -pipe $SHARED -o cmd_$cmd.so cmd_$cmd.o
1730 # Routine to list out the extra/ modules that have been enabled.
1731 # Note: when getting any filenames out and comparing, it's important to lc it if the
1732 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1733 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1734 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1735 sub list_extras () {
1738 my $srcdir = File::Spec->catdir("src", "modules");
1739 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1742 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1743 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1746 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1747 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1750 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1752 EXTRA: for my $extra (@extras) {
1753 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1754 next if ($extra eq '.svn');
1755 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1756 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1757 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1758 if (-l $abs_source) {
1759 # Symlink, is it in the right place?
1760 my $targ = readlink($abs_source);
1761 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1762 if ($abs_targ eq $abs_extra) {
1763 $extras{$extra} = "\e[32;1menabled\e[0m";
1765 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1767 } elsif (-e $abs_source) {
1768 my ($devext, $inoext) = stat($abs_extra);
1769 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1771 if ($devsrc == $devext && $inosrc == $inoext) {
1772 $extras{$extra} = "\e[32;1menabled\e[0m";
1774 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1777 open my $extfd, "<", $abs_extra;
1778 open my $srcfd, "<", $abs_source;
1780 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1781 $extras{$extra} = "\e[32;1menabled\e[0m";
1783 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1787 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1790 # Now let's add dependency info
1791 for my $extra (keys(%extras)) {
1792 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1793 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1794 my @deps = split / +/, getdependencies($abs_extra);
1795 for my $dep (@deps) {
1796 if (exists($extras{$dep})) {
1797 my $ref = \$extras{$dep}; # Take reference.
1798 if ($$ref !~ m/needed by/) {
1799 # First dependency found.
1800 if ($$ref =~ m/enabled/) {
1801 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1803 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1804 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1807 if ($$ref =~ m/enabled/) {
1808 $$ref .= ", \e[32;1m$extra\e[0m";
1810 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1816 for my $extra (sort {$a cmp $b} keys(%extras)) {
1817 my $text = $extras{$extra};
1818 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1819 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1821 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1824 return keys(%extras) if wantarray; # Can be used by manage_extras.
1827 sub enable_extras (@) {
1829 for my $extra (@extras) {
1830 my $extrapath = "src/modules/extra/$extra";
1831 if (!-e $extrapath) {
1832 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1835 my $source = "src/modules/$extra";
1837 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1840 # Get dependencies, and add them to be processed.
1841 my @deps = split / +/, getdependencies($extrapath);
1842 for my $dep (@deps) {
1843 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1844 if (!-e "src/modules/$dep") {
1845 if (-e "src/modules/extra/$dep") {
1846 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1849 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";
1853 print "Enabling $extra ... \n";
1854 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1858 sub disable_extras (@)
1860 opendir my $dd, "src/modules/extra/";
1861 my @files = readdir($dd);
1864 EXTRA: for my $extra (@extras) {
1865 my $extrapath = "src/modules/extra/$extra";
1866 my $source = "src/modules/$extra";
1867 if (!-e $extrapath) {
1868 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1871 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1872 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";
1875 # Check if anything needs this.
1876 for my $file (@files) {
1877 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1878 # File depends on this extra...
1879 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1880 # And is both enabled and not about to be disabled.
1881 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1882 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1888 print "Disabling $extra ... \n";
1889 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";