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_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 'enable-ports' => \$opt_ports,
127 'enable-epoll' => \$opt_epoll,
128 'enable-kqueue' => \$opt_kqueue,
129 'disable-ports' => \$opt_noports,
130 'disable-epoll' => \$opt_noepoll,
131 'disable-kqueue' => \$opt_nokqueue,
132 'disable-rpath' => \$opt_disablerpath,
133 'enable-ipv6' => \$opt_ipv6,
134 'enable-remote-ipv6' => \$opt_ipv6links,
135 'disable-remote-ipv6' => \$opt_noipv6links,
136 'with-cc=s' => \$opt_cc,
137 'with-ident-length=i' => \$opt_ident,
138 'with-quit-length=i' => \$opt_quit,
139 'with-topic-length=i' => \$opt_topic,
140 'with-maxbuf=i' => \$opt_maxbuf,
141 'with-kick-length=i' => \$opt_kick,
142 'with-gecos-length=i' => \$opt_gecos,
143 'with-away-length=i' => \$opt_away,
144 'with-max-modes=i' => \$opt_modes,
145 'prefix=s' => \$opt_base_dir,
146 'config-dir=s' => \$opt_config_dir,
147 'module-dir=s' => \$opt_module_dir,
148 'binary-dir=s' => \$opt_binary_dir,
149 'library-dir=s' => \$opt_library_dir,
150 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
151 'help' => sub { showhelp(); },
152 'modupdate' => sub { modupdate(); },
153 'update' => sub { update(); },
154 'svnupdate' => sub { svnupdate(); },
155 'clean' => sub { clean(); },
156 'list-extras' => sub { list_extras; exit 0; }, # This, --enable-extras, and --disable-extras are for non-interactive managing.
157 'enable-extras=s@' => \@opt_enableextras, # ^
158 'disable-extras=s@' => \@opt_disableextras, # ^
161 if (scalar(@opt_enableextras) + scalar(@opt_disableextras) > 0) {
162 @opt_enableextras = split /,/, join(',', @opt_enableextras);
163 @opt_disableextras = split /,/, join(',', @opt_disableextras);
164 enable_extras(@opt_enableextras);
165 disable_extras(@opt_disableextras);
167 print "Remember: YOU are responsible for making sure any libraries needed have been installed!\n";
168 print "Run $0 -modupdate after you've done this to update the makefiles.\n";
172 our $non_interactive = (
173 (defined $opt_library_dir) ||
174 (defined $opt_base_dir) ||
175 (defined $opt_config_dir) ||
176 (defined $opt_module_dir) ||
177 (defined $opt_base_dir) ||
178 (defined $opt_binary_dir) ||
179 (defined $opt_nointeractive) ||
180 (defined $opt_away) ||
181 (defined $opt_gecos) ||
182 (defined $opt_kick) ||
183 (defined $opt_modes) ||
184 (defined $opt_topic) ||
185 (defined $opt_quit) ||
186 (defined $opt_ident) ||
188 (defined $opt_ipv6) ||
189 (defined $opt_ipv6links) ||
190 (defined $opt_noipv6links) ||
191 (defined $opt_kqueue) ||
192 (defined $opt_epoll) ||
193 (defined $opt_ports) ||
194 (defined $opt_maxchans) ||
195 (defined $opt_opermaxchans) ||
196 (defined $opt_chan_length) ||
197 (defined $opt_nick_length) ||
198 (defined $opt_use_openssl) ||
199 (defined $opt_nokqueue) ||
200 (defined $opt_noepoll) ||
201 (defined $opt_noports) ||
202 (defined $opt_maxbuf) ||
203 (defined $opt_use_gnutls)
205 our $interactive = !$non_interactive;
207 chomp(our $topdir = getcwd());
208 our $this = resolve_directory($topdir); # PWD, Regardless.
209 our @modlist = (); # Declare for Module List..
210 our %config = (); # Initiate Configuration Hash..
211 $config{ME} = resolve_directory($topdir); # Present Working Directory
213 $config{BASE_DIR} = $config{ME};
215 if (defined $opt_base_dir)
217 $config{BASE_DIR} = $opt_base_dir;
220 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
221 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
222 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
223 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
225 if (defined $opt_config_dir)
227 $config{CONFIG_DIR} = $opt_config_dir;
229 if (defined $opt_module_dir)
231 $config{MODULE_DIR} = $opt_module_dir;
233 if (defined $opt_binary_dir)
235 $config{BINARY_DIR} = $opt_binary_dir;
237 if (defined $opt_library_dir)
239 $config{LIBRARY_DIR} = $opt_library_dir;
241 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
242 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version
243 chomp(our $gnutls_ver = $config{HAS_GNUTLS});
244 chomp(our $openssl_ver = $config{HAS_OPENSSL});
245 $config{USE_GNUTLS} = "n";
246 if (defined $opt_use_gnutls)
248 $config{USE_GNUTLS} = "y"; # Use gnutls.
250 $config{USE_OPENSSL} = "n"; # Use openssl.
251 if (defined $opt_use_openssl)
253 $config{USE_OPENSSL} = "y";
256 # no, let's not change these.
257 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
258 if (!defined $opt_disable_debug)
260 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
264 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
267 $config{NICK_LENGT} = "31"; # Default Nick Length
268 if (defined $opt_nick_length)
270 $config{NICK_LENGT} = $opt_nick_length;
272 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
273 if (defined $opt_chan_length)
275 $config{CHAN_LENGT} = $opt_chan_length;
277 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
278 if (defined $opt_modes)
280 $config{MAXI_MODES} = $opt_modes;
282 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
283 $config{HAS_STDINT} = "false"; # stdint.h check
284 $config{USE_KQUEUE} = "y"; # kqueue enabled
285 if (defined $opt_kqueue)
287 $config{USE_KQUEUE} = "y";
289 if (defined $opt_nokqueue)
291 $config{USE_KQUEUE} = "n";
293 $config{USE_EPOLL} = "y"; # epoll enabled
294 if (defined $opt_epoll)
296 $config{USE_EPOLL} = "y";
298 if (defined $opt_noepoll)
300 $config{USE_EPOLL} = "n";
302 $config{USE_PORTS} = "y"; # epoll enabled
303 if (defined $opt_ports)
305 $config{USE_PORTS} = "y";
307 if (defined $opt_noports)
309 $config{USE_PORTS} = "n";
311 $config{IPV6} = "n"; # IPv6 support (experimental)
312 if (defined $opt_ipv6)
316 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
317 if (defined $opt_ipv6links)
319 $config{SUPPORT_IP6LINKS} = "y";
321 if (defined $opt_noipv6links)
323 $config{SUPPORT_IP6LINKS} = "n";
325 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
326 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
327 $config{OSNAME} = $^O; # Operating System Name
328 $config{IS_DARWIN} = "NO"; # Is OSX?
329 $config{STARTSCRIPT} = "inspircd"; # start script?
330 $config{DESTINATION} = "BASE"; # Is target path.
331 $config{EXTRA_DIR} = ""; # Is empty.
332 if ($config{OSNAME} =~ /darwin/i)
334 $config{IS_DARWIN} = "YES";
335 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
336 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
337 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
339 $config{CC} = "g++"; # C++ compiler
342 $config{CC} = $opt_cc;
344 our $exec = $config{CC} . " -dumpversion | cut -c 1";
345 chomp($config{GCCVER} = `$exec`); # Major GCC Version
346 $config{MAKEORDER} = "ircd mods"; # build order
347 $config{MAX_IDENT} = "12"; # max ident size
348 $config{MAX_QUIT} = "255"; # max quit message size
349 $config{MAX_TOPIC} = "307"; # max topic size
350 $config{MAX_KICK} = "255"; # max kick message size
351 $config{MAX_GECOS} = "128"; # max GECOS size
352 $config{MAX_AWAY} = "200"; # max AWAY size
353 $config{MAXBUF} = "512"; # Max buffer size
354 if (defined $opt_ident)
356 $config{MAX_IDENT} = $opt_ident;
358 if (defined $opt_quit)
360 $config{MAX_QUIT} = $opt_quit;
362 if (defined $opt_topic)
364 $config{MAX_TOPIC} = $opt_topic;
366 if (defined $opt_kick)
368 $config{MAX_KICK} = $opt_kick;
370 if (defined $opt_gecos)
372 $config{MAX_GECOS} = $opt_gecos;
374 if (defined $opt_away)
376 $config{MAX_AWAY} = $opt_away;
379 if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) {
380 $config{HAS_OPENSSL} = $1;
382 $config{HAS_OPENSSL} = "";
385 if ($config{GCCVER} eq "") {
386 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
390 # Get and Set some important vars..
395 unlink(".config.cache");
398 our ($has_epoll, $has_ports, $has_kqueue) = (0, 0, 0);
403 chomp($topdir = getcwd());
404 $this = resolve_directory($topdir); # PWD, Regardless.
406 # Does the cache file exist?
408 # No, No it doesn't.. *BASH*
409 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
412 # We've Loaded the cache file and all our variables..
413 print "Updating files...\n";
415 if (defined($opt_disable_debug) && $opt_disable_debug == 1)
417 print "Disabling debug information (-g).\n";
418 $config{OPTIMISATI} = "";
421 $has_epoll = $config{HAS_EPOLL};
422 $has_ports = $config{HAS_PORTS};
423 $has_kqueue = $config{HAS_KQUEUE};
432 print "Configure update failed: $@\n";
440 chomp($topdir = getcwd());
441 $this = resolve_directory($topdir); # PWD, Regardless.
443 # Does the cache file exist?
445 # No, No it doesn't.. *BASH*
446 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
449 # We've Loaded the cache file and all our variables..
450 print "Updating files...\n";
452 $has_epoll = $config{HAS_EPOLL};
453 $has_ports = $config{HAS_PORTS};
454 $has_kqueue = $config{HAS_KQUEUE};
463 print "Module update failed: $@\n";
473 open(FH,"<.svn/entries") or $fail = 1;
475 print "This is not an SVN copy of InspIRCd.\n";
482 open my $fd, "-|", "svn update";
483 my $configurechanged = 0; # Needs ./configure -update
484 my $coredirchanged = 0; # Needs ./configure -update
485 my $moduledirchanged = 0; # Needs ./configure -modupdate
486 my $rootincchanged = 0;
488 while (defined(my $line = <$fd>))
492 $line =~ m/^([ADUCG])\s+(.*)$/ or next;
493 ($action, $file) = ($1, $2);
496 push @conflicted, $file;
497 if ($file eq "configure")
499 $configurechanged = 1;
501 elsif ($file =~ m#^src/modules#)
503 $moduledirchanged = 1;
505 elsif ($file =~ m#^src/#)
509 elsif ($file =~ m/^\..*\.inc$/)
514 elsif ($action eq "U" || $action eq "G")
516 if ($file eq "configure")
518 $configurechanged = 1;
520 elsif ($file =~ m/^\..*\.inc$/)
525 elsif ($action eq "A" || $action eq "D")
527 if ($file =~ m#^src/modules#)
529 $moduledirchanged = 1;
531 elsif ($file =~ m#^src/#)
537 unless (close $fd) # close() waits for exit and returns false if the command failed
541 print STDERR "Problem updating from SVN, please check above for errors\n";
545 print STDERR "Failed to run SVN: $!\n";
549 if (scalar(@conflicted) > 0)
551 print STDERR "\e[0;33;1mERROR:\e[0m You have local modifications which conflicted with the updates from SVN\n";
552 printf STDERR "Configure is not able to complete the update. Please resolve these conflicts, then run ./configure -%supdate\n", (($coredirchanged || $configurechanged) ? "" : "mod");
553 print "Conflicted files: " . join ", ", @conflicted . "\n";
556 if ($configurechanged || $coredirchanged)
558 system("perl configure -update");
560 elsif ($moduledirchanged || $rootincchanged)
562 system("perl configure -modupdate");
566 print "No need to update Makefiles.\n";
568 if (defined $opt_rebuild) {
569 system("make install");
574 print "Running non-interactive configure...\n" unless $interactive;
575 print "Checking for cache from previous configure... ";
576 print ((!getcache()) ? "not found\n" : "found\n");
577 print "Checking operating system version... ";
578 print getosflags() . "\n";
580 printf "Checking if stdint.h exists... ";
581 $config{HAS_STDINT} = "true";
583 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
584 if ($config{HAS_STDINT} eq "true") {
587 print "yes\n" if $config{HAS_STDINT} eq "true";
588 print "no\n" if $config{HAS_STDINT} eq "false";
590 printf "Checking if strlcpy exists... ";
591 # Perform the strlcpy() test..
592 $config{HAS_STRLCPY} = "false";
594 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
596 while (defined(my $line = <STRLCPY>)) {
598 # try and find the delcaration of:
599 # size_t strlcpy(...)
600 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
601 $config{HAS_STRLCPY} = "true";
606 print "yes\n" if $config{HAS_STRLCPY} eq "true";
607 print "no\n" if $config{HAS_STRLCPY} eq "false";
609 printf "Checking if kqueue exists... ";
612 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
614 while (defined(my $line = <KQUEUE>)) {
616 # try and find the delcaration of:
618 if ($line =~ /int(\0x9|\s)+kqueue/) {
624 print "yes\n" if $has_kqueue == 1;
625 print "no\n" if $has_kqueue == 0;
627 printf "Checking if epoll exists... ";
630 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
636 my $kernel = `uname -r`;
638 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
643 # Suggestion from nenolod, weed out odd systems which have glibc built
644 # against 2.4 kernels (ick)
645 my $kernel_arch = `uname -p`;
649 if ($kernel_arch =~ /x86_64/) {
650 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
653 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
657 while (defined(my $line = <FH>))
660 if ($line =~ /GNU C Library .* version (.*?) /)
663 $libcv =~ /(\d+\.\d+)/;
666 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
669 # Fix for some retarded libc builds, strip off >> and << etc.
670 $kernelv =~ /(\d+\.\d+)/;
678 printf "libc too old: $libcv... ";
683 printf "libc built against older kernel $kernelv... ";
688 print "yes\n" if $has_epoll == 1;
689 print "no\n" if $has_epoll == 0;
691 printf "Checking if Solaris I/O completion ports are available... ";
693 our $system = `uname -s`;
695 $has_ports = 1 if ($system eq "SunOS");
698 my $kernel = `uname -r`;
700 if (($kernel !~ /^5\.1./)) {
704 print "yes\n" if $has_ports == 1;
705 print "no\n" if $has_ports == 0;
707 $config{HAS_EPOLL} = $has_epoll;
708 $config{HAS_KQUEUE} = $has_kqueue;
710 printf "Checking for libgnutls... ";
711 if (defined($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS}) || ($config{HAS_GNUTLS} eq "y"))) {
713 $config{HAS_GNUTLS} = "y";
716 $config{HAS_GNUTLS} = "n";
719 printf "Checking for openssl... ";
720 if (defined($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL}) || ($config{HAS_OPENSSL} eq "y"))) {
722 $config{HAS_OPENSSL} = "y";
725 $config{HAS_OPENSSL} = "n";
728 printf "Checking if you are running an ancient, unsupported OS... ";
729 if ($config{OSNAME} =~ /FreeBSD/i)
731 my $version = `uname -r`;
732 if ($version =~ /^4\./)
734 my $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
737 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
738 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
743 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
749 print "no ($version)\n";
755 print "no ($config{OSNAME})\n";
758 ################################################################################
759 # BEGIN INTERACTIVE PART #
760 ################################################################################
765 print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
768 my $rev = getrevision();
769 # Display Introduction Message..
771 Welcome to the \e[1mInspIRCd\e[0m Configuration program! (\e[1minteractive mode\e[0m)
772 \e[1mPackage maintainers: Type ./configure --help for non-interactive help\e[0m
774 *** If you are unsure of any of these values, leave it blank for ***
775 *** standard settings that will work, and your server will run ***
776 *** using them. Please consult your IRC network admin if in doubt. ***
778 Press \e[1m<RETURN>\e[0m to accept the default for any option, or enter
779 a new value. Please note: You will \e[1mHAVE\e[0m to read the docs
780 dir, otherwise you won't have a config file!
782 Your operating system is: \e[1;32m$config{OSNAME}\e[0m ($wholeos)
783 Your InspIRCd revision ID is \e[1;32mr$rev\e[0m
786 print " (Non-SVN build)";
790 $config{CHANGE_COMPILER} = "n";
791 print "I have detected the following compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
793 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
794 print "\e[1;32mIMPORTANT!\e[0m A GCC 2.x compiler has been detected, and
795 should NOT be used. You should probably specify a newer compiler.\n\n";
796 yesno('CHANGE_COMPILER',"Do you want to change the compiler?");
797 if ($config{CHANGE_COMPILER} =~ /y/i) {
798 print "What command do you want to use to invoke your compiler?\n";
799 print "[\e[1;32m$config{CC}\e[0m] -> ";
800 chomp($config{CC} = <STDIN>);
801 if ($config{CC} eq "") {
804 chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`);
806 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
807 print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.x\e[0m)\n";
808 if ($config{GCCVER} < 3) {
809 print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n";
813 print "\e[1;32mWARNING!\e[0m Could not execute the compiler you specified. You may want to try again.\n";
820 # Directory Settings..
821 my $tmpbase = $config{BASE_DIR};
822 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
823 if ($tmpbase ne $config{BASE_DIR}) {
824 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
825 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
826 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
827 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
830 dir_check("are the configuration files", "CONFIG_DIR");
831 dir_check("are the modules to be compiled to", "MODULE_DIR");
832 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
833 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
836 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?");
840 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?");
844 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?");
847 my $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
848 if (!$chose_hiperf) {
849 print "No high-performance socket engines are available, or you chose\n";
850 print "not to enable one. Defaulting to select() engine.\n\n";
853 yesno('IPV6',"Would you like to build InspIRCd with IPv6 support?");
856 if ($config{IPV6} eq "y") {
857 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";
858 $config{SUPPORT_IP6LINKS} = "y";
860 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)");
864 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
865 print "I have detected both \e[1;32mGnuTLS\e[0m and \e[1;32mOpenSSL\e[0m on your system.\n";
866 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
867 print "instead, you should enable the OpenSSL module yourself\n";
868 print "by copying it from src/modules/extra to src/modules.\n\n";
869 print "Detected GnuTLS version: \e[1;32m" . $gnutls_ver . "\e[0m\n";
870 print "Detected OpenSSL version: \e[1;32m" . $openssl_ver . "\e[0m\n\n";
873 if ($config{HAS_GNUTLS} eq "y") {
874 yesno('USE_GNUTLS', "Would you like to enable SSL Support?");
875 if ($config{USE_GNUTLS} eq "y") {
876 print "\nUsing GnuTLS SSL module.\n";
878 } elsif ($config{HAS_OPENSSL} eq "y") {
879 yesno('USE_OPENSSL', "Would you like to enable SSL Support?");
880 if ($config{USE_OPENSSL} eq "y") {
881 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
885 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";
888 print "\nThe following questions will ask you for various figures relating\n";
889 print "To your IRCd install. Please note that these should usually be left\n";
890 print "as defaults unless you have a real reason to change them. If they\n";
891 print "changed, then the values must be identical on all servers on your\n";
892 print "network, or malfunctions and/or crashes may occur, with the exception\n";
893 print "of the 'maximum number of clients' setting which may be different on\n";
894 print "different servers on the network.\n\n";
896 promptnumeric("length of nicknames", "NICK_LENGT");
897 promptnumeric("length of channel names", "CHAN_LENGT");
898 promptnumeric("number of mode changes in one line", "MAXI_MODES");
899 promptnumeric("length of an ident (username)", "MAX_IDENT");
900 promptnumeric("length of a quit message", "MAX_QUIT");
901 promptnumeric("length of a channel topic", "MAX_TOPIC");
902 promptnumeric("length of a kick message", "MAX_KICK");
903 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
904 promptnumeric("length of an away message", "MAX_AWAY");
909 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
911 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
914 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
916 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
921 if ($config{USE_GNUTLS} eq "y") {
922 unless (-r "src/modules/m_ssl_gnutls.cpp") {
923 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
924 symlink "extra/m_ssl_gnutls.cpp", "src/modules/m_ssl_gnutls.cpp" or print STDERR "Symlink failed: $!";
929 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
930 print "SSL Certificates Not found, Generating.. \n\n
931 *************************************************************
932 * Generating the Private Key may take some time, go grab a *
933 * Coffee. Even better, to generate some more entropy if it *
934 * is taking a while, open another console and type du / a *
935 * few times and get that HD going :) Then answer the *
936 * Questions which follow. If you are unsure, just hit enter *
937 *************************************************************\n\n";
938 $failed = make_gnutls_cert();
940 print "\n\e[1;32mCertificate generation failed!\e[0m\n\n";
942 print "\nCertificate generation complete, copying to config directory... ";
943 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
944 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
949 print "SSL Certificates found, skipping.\n\n";
954 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
956 } elsif ($config{USE_OPENSSL} eq "y") {
957 unless (-r "src/modules/m_ssl_openssl.cpp") {
958 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
959 symlink "extra/m_ssl_openssl.cpp", "src/modules/m_ssl_openssl.cpp" or print STDERR "Symlink failed: $!";
965 unless (-r "$config{CONFIG_DIR}/key.pem" && -r "$config{CONFIG_DIR}/cert.pem") {
966 print "SSL Certificates Not found, Generating.. \n\n
967 *************************************************************
968 * Generating the certificates may take some time, go grab a *
969 * coffee, or something. *
970 *************************************************************\n\n";
972 print "\nCertificate generation complete, copying to config directory... ";
973 File::Copy::move("key.pem", "$config{CONFIG_DIR}/key.pem") or print STDERR "Could not copy key.pem!\n";
974 File::Copy::move("cert.pem", "$config{CONFIG_DIR}/cert.pem") or print STDERR "Could not copy cert.pem!\n";
975 File::Copy::move("dhparams.pem", "$config{CONFIG_DIR}/dhparams.pem") or print STDERR "Could not copy dhparams.pem!\n";
978 print "SSL Certificates found, skipping.\n\n"
983 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
986 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
987 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
995 print "To build your server with these settings, please type '\e[1;32m$config{MAKEPROG}\e[0m' now.\n";
996 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
997 print "Please note: for \e[1;32mSSL support\e[0m you will need to load required\n";
998 print "modules in your config. This configure script has added those modules to the\n";
999 print "build process. For more info please refer to:\n";
1000 print "\e[1;32mhttp://www.inspircd.org/wiki/Installation_From_Tarball\e[0m\n";
1002 print "*** \e[1;32mRemember to edit your configuration files!!!\e[0m ***\n\n\n";
1003 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
1004 print "\e[1;32mWARNING!\e[0m You are running OpenBSD but you are using the base gcc package\nrather than eg++. This compile will most likely fail, but i'm letting you\ngo ahead with it anyway, just in case i'm wrong :-)\n";
1007 if ($config{GCCVER} < "3") {
1009 \e[1;32mWARNING!\e[0m You are attempting to compile InspIRCd on GCC 2.x!
1010 GCC 2.x series compilers only had partial (read as broken) C++ support, and
1011 your compile will most likely fail horribly! If you have any problems, do NOT
1012 report them to the bugtracker or forums without first upgrading your compiler
1013 to a newer 3.x or 4.x (or whatever is available currently) version.
1017 ################################################################################
1018 # HELPER FUNCTIONS #
1019 ################################################################################
1021 # Retrieves the .config.cache file, and loads values into the main config hash.
1022 open(CACHE, ".config.cache") or return 0;
1025 # Ignore Blank lines, and comments..
1028 my ($key, $value) = split("=", $_, 2);
1029 $value =~ /^\"(.*)\"$/;
1030 # Do something with data here!
1038 # Dump the contents of %config
1039 print "Writing \e[1;32mcache file\e[0m for future ./configures ...\n";
1040 open(FILEHANDLE, ">.config.cache");
1041 foreach my $key (keys %config) {
1042 print FILEHANDLE "$key=\"$config{$key}\"\n";
1048 my ($desc, $hash_key) = @_;
1050 while (!$complete) {
1051 print "In what directory $desc?\n";
1052 print "[\e[1;32m$config{$hash_key}\e[0m] -> ";
1053 chomp(my $var = <STDIN>);
1055 $var = $config{$hash_key};
1057 if ($var =~ /^\~\/(.+)$/) {
1058 # Convert it to a full path..
1059 $var = resolve_directory($ENV{HOME} . "/" . $1);
1061 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
1063 # Assume relative Path was given.. fill in the rest.
1064 $var = $this . "/$var";
1067 $var = resolve_directory($var);
1069 print "$var does not exist. Create it?\n[\e[1;32my\e[0m] ";
1070 chomp(my $tmp = <STDIN>);
1071 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1072 # Attempt to Create the Dir..
1075 File::Path::mkpath($var, 0, 0777);
1078 unless (defined($chk) && -d $var) {
1079 print "Unable to create directory. ($var)\n\n";
1084 # They said they don't want to create, and we can't install there.
1089 if (!is_dir($var)) {
1090 # Target exists, but is not a directory.
1091 print "File $var exists, but is not a directory.\n\n";
1095 # Either Dir Exists, or was created fine.
1096 $config{$hash_key} = $var;
1106 # Beware: Linux sets it's own cflags below for some retarded reason
1107 $config{LDLIBS} = "-pthread -lstdc++";
1108 $config{FLAGS} = "-fPIC -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall $config{OPTIMISATI}";
1109 $config{DEVELOPER} = "-fPIC -Woverloaded-virtual -Wshadow -Wall -Wformat=2 -Wmissing-format-attribute -g";
1110 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared" unless defined $opt_disablerpath;
1111 $config{MAKEPROG} = "make";
1113 if ($config{OSNAME} =~ /darwin/i) {
1114 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall $config{OPTIMISATI}";
1115 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1116 $config{LDLIBS} = "-ldl -pthread -lstdc++";
1119 if ($config{OSNAME} =~ /OpenBSD/i) {
1120 $config{MAKEPROG} = "gmake";
1121 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1122 chomp(my $foo = `eg++ -dumpversion | cut -c 1`);
1123 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1124 # if theyre not running this, configure lets the build continue but they probably wont manage to
1125 # compile as this standard version is 2.95.3!
1127 $config{CC} = "eg++";
1128 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
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 my $NL = $config{NICK_LENGT}+1;
1182 my $CL = $config{CHAN_LENGT}+1;
1183 print FILEHANDLE <<EOF;
1184 /* Auto generated by configure, do not modify! */
1185 #ifndef __CONFIGURATION_AUTO__
1186 #define __CONFIGURATION_AUTO__
1188 /* this is for windows support. */
1189 #define CoreExport /**/
1190 #define DllExport /**/
1192 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1193 #define MOD_PATH "$config{MODULE_DIR}"
1194 #define VERSION "$version"
1195 #define REVISION "$revision2"
1196 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1199 #define MAXMODES $config{MAXI_MODES}
1200 #define IDENTMAX $config{MAX_IDENT}
1201 #define MAXQUIT $config{MAX_QUIT}
1202 #define MAXTOPIC $config{MAX_TOPIC}
1203 #define MAXKICK $config{MAX_KICK}
1204 #define MAXGECOS $config{MAX_GECOS}
1205 #define MAXAWAY $config{MAX_AWAY}
1206 #define OPTIMISATION $config{OPTIMITEMP}
1207 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1208 #define SYSTEM "$incos"
1211 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1213 if ($config{OSNAME} =~ /SunOS/i) {
1214 print FILEHANDLE "#define IS_SOLARIS\n";
1216 if ($config{OSNAME} =~ /MINGW32/i) {
1217 print FILEHANDLE "#define IS_MINGW\n";
1219 if ($config{GCCVER} >= 3) {
1220 print FILEHANDLE "#define GCC3\n";
1222 if ($config{HAS_STRLCPY} eq "true") {
1223 print FILEHANDLE "#define HAS_STRLCPY\n";
1225 if ($config{HAS_STDINT} eq "true") {
1226 print FILEHANDLE "#define HAS_STDINT\n";
1228 if ($config{IPV6} =~ /y/i) {
1229 print FILEHANDLE "#define IPV6\n";
1231 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1232 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1235 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1236 print FILEHANDLE "#define USE_KQUEUE\n";
1237 $se = "socketengine_kqueue";
1240 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1241 print FILEHANDLE "#define USE_EPOLL\n";
1242 $se = "socketengine_epoll";
1245 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1246 print FILEHANDLE "#define USE_PORTS\n";
1247 $se = "socketengine_ports";
1250 # user didn't choose either epoll or select for their OS.
1251 # default them to USE_SELECT (ewwy puke puke)
1253 print FILEHANDLE "#define USE_SELECT\n";
1254 $se = "socketengine_select";
1256 print FILEHANDLE "\n#include \"threadengines/threadengine_pthread.h\"\n\n#endif\n";
1262 open(FILEHANDLE, ">include/inspircd_se_config.h");
1263 print FILEHANDLE <<EOF;
1264 /* Auto generated by configure, do not modify or commit to svn! */
1265 #ifndef __CONFIGURATION_SOCKETENGINE__
1266 #define __CONFIGURATION_SOCKETENGINE__
1268 #include "socketengines/$se.h"
1276 # Create a Modules List..
1278 foreach my $i (@modlist)
1280 $modules .= "m_".$i.".so ";
1282 chomp($modules); # Remove Redundant whitespace..
1284 opendir(DIRHANDLE, "src/modules");
1285 foreach my $name (sort readdir(DIRHANDLE)) {
1286 if ($name =~ /^m_(.+?)$/) {
1287 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1288 closedir(MDIRHANDLE);
1289 $modules .= "$name.so ";
1290 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/$name.so\n";
1294 closedir(DIRHANDLE);
1297 # Write all .in files.
1300 my $exe = "inspircd";
1302 # Do this once here, and cache it in the .*.inc files,
1303 # rather than attempting to read src/version.sh from
1304 # compiled code -- we might not have the source to hand.
1305 # Fix for bug#177 by Brain.
1307 chomp($version = `sh ./src/version.sh`);
1308 chomp(my $revision = getrevision());
1309 $version = "$version(r$revision)";
1311 # We can actually parse any file starting with . and ending with .inc,
1312 # but right now we only parse .inspircd.inc to form './inspircd'
1314 print "Writing \e[1;32mMakefiles\e[0m\n";
1315 write_dynamic_modules_makefile();
1316 write_dynamic_makefile();
1318 opendir(DIRHANDLE, $this);
1320 foreach my $name (sort readdir(DIRHANDLE)) {
1321 if ($name =~ /^\.(.+)\.inc$/) {
1324 # Bug #353, omit this on non-darwin
1325 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1327 # All .name.inc files need parsing!
1329 open(FILEHANDLE, ".$file.inc") or die ("Can't open .$file.inc");
1330 while (<FILEHANDLE>) {
1335 print "Writing \e[1;32m$file\e[0m ...\n";
1336 $tmp =~ s/\@CC\@/$config{CC}/ if defined $config{CC};
1337 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/ if defined $config{MAKEPROG};
1338 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/ if defined $config{FLAGS};
1339 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/ if defined $config{DEVELOPER};
1340 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/ if defined $config{LDLIBS};
1341 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/ if defined $config{BASE_DIR};
1342 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/ if defined $config{CONFIG_DIR};
1343 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/ if defined $config{MODULE_DIR};
1344 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/ if defined $config{BINARY_DIR};
1345 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/ if defined $config{LIBRARY_DIR};
1346 $tmp =~ s/\@MODULES\@/$modules/ if defined $modules;
1347 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/ if defined $config{STARTSCRIPT};
1348 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/ if defined $config{DESTINATION};
1349 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/ if defined $config{EXTRA_DIR};
1350 $tmp =~ s/\@EXECUTABLE\@/$exe/ if defined $exe;
1351 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/ if defined $config{MAKEORDER};
1352 $tmp =~ s/\@VERSION\@/$version/ if defined $version;
1353 $tmp =~ s/\@INSTALL_LIST\@/$install_list/ if defined $install_list;
1354 $tmp =~ s/\@UNINSTALL_LIST\@/$uninstall_list/ if defined $uninstall_list;
1356 open(FILEHANDLE, ">$file");
1357 print FILEHANDLE $tmp;
1360 closedir(DIRHANDLE);
1362 # Make inspircd executable!
1363 chmod 0744, 'inspircd';
1366 sub write_dynamic_modules_makefile {
1367 # Modules Makefile..
1368 print "Writing \e[1;32msrc/modules/Makefile\e[0m\n";
1369 open(FILEHANDLE, ">src/modules/Makefile");
1372 # Module Makefile Header
1374 print FILEHANDLE <<EOF;
1375 ###################################################
1376 # Copyright 2002-2007 The InspIRCd Development Team
1377 # http://www.inspircd.org/wiki/index.php/Credits
1379 # Thanks to Andrew Church <achurch\@achurch.org>
1380 # for assisting with making this work right.
1382 # Automatically Generated by ./configure to add a
1383 # modules please run ./configure -modupdate
1384 ###################################################
1390 if ($config{OSNAME} =~ /darwin/) {
1391 print FILEHANDLE <<EOCHEESE;
1393 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup -bundle
1397 print FILEHANDLE <<EOCHEESE;
1399 PICLDFLAGS = -fPIC -DPIC -shared
1405 # End Module Makefile Header
1408 # Create a Modules List..
1412 foreach my $i (@modlist) {
1414 # Write Entry to the MakeFile
1416 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1417 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1418 my $deps = getdependencies("src/modules/m_".$i.".cpp");
1420 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1423 if (nopedantic("src/modules/m_".$i.".cpp"))
1426 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
1427 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(NICEFLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1433 m_$i.so: m_$i.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h ../../include/inspircd_config.h ../../include/inspircd.h ../../include/configreader.h $deps
1434 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1437 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/m_$i.so \$(MODPATH)\n";
1438 $uninstall_list = $uninstall_list . " -rm \$(MODULES)/m_$i.so\n";
1440 # End Write Entry to the MakeFile
1444 opendir(DIRHANDLE, "src/modules");
1445 foreach my $name (sort readdir(DIRHANDLE)) {
1446 if ($name =~ /^m_(.+?)$/) {
1451 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1452 if (defined(opendir(MDIRHANDLE, "src/modules/$name"))) {
1453 read_module_directory("src/modules/$name", $name);
1454 print "Composing Makefile rules for directory \e[1;32m$name\e[0m... (\e[1;32m$mfcount files found\e[0m)\n";
1455 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";
1456 if ($config{IS_DARWIN} eq "YES") {
1457 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1459 print FILEHANDLE " \@../../make/run-cc.pl \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1461 print FILEHANDLE "\n$mfrules\n";
1462 closedir(MDIRHANDLE);
1463 $install_list = $install_list . " install -m \$(INSTMODE) src/modules/$name.so \$(MODPATH)\n";
1467 closedir(DIRHANDLE);
1470 sub read_module_directory {
1471 my ($dpath, $reldpath) = @_;
1473 if (opendir(MDIRHANDLE, $dpath) == 0) {
1477 foreach my $fname (sort readdir(MDIRHANDLE)) {
1478 if ($fname =~ /\.cpp$/) {
1479 my $cmflags = getcompilerflags("$dpath/$fname");
1480 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1481 my $deps = getdependencies("$dpath/$fname");
1483 $oname =~ s/\.cpp$/.o/g;
1484 $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";
1485 $mfrules = $mfrules . " \@../../make/run-cc.pl \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1486 $mobjs = $mobjs . " $reldpath/$oname";
1489 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1490 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1497 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1498 # dependencies which are not relevent in C++.
1502 open (CPP, "<$file") or die("Can't open $file for reading!");
1507 foreach my $d (@ignoredeps)
1513 foreach my $dep (@immutabledeps)
1515 $immutable = $immutable . "../include/$dep ";
1517 $immutable =~ s/ $//g;
1519 while (defined(my $line = <CPP>))
1522 if ($line =~ /#include "(.+\.h)"/)
1524 if (!exists($dupe{$1}))
1526 $retlist = $retlist . "../include/$1 ";
1532 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1535 sub write_dynamic_makefile
1539 my %existing_install_list = ();
1540 opendir(DIRHANDLE, "src/commands");
1541 foreach my $name (sort readdir(DIRHANDLE))
1543 if ($name =~ /^cmd_(.+)\.cpp$/)
1545 $cmdlist[$i++] = $1;
1546 $install_list = $install_list . " -install -m \$(INSTMODE) src/commands/cmd_" . $1 . ".so \$(LIBPATH)\n";
1547 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/cmd_$1.so\n";
1550 closedir(DIRHANDLE);
1554 $config{USE_EPOLL} = 0;
1558 $config{USE_KQUEUE} = 0;
1562 $config{USE_PORTS} = 0;
1565 foreach my $dir (("src","src/commands","src/modes","src/socketengines","src/modules"))
1567 print "Scanning \e[1;32m$dir\e[0m for core files ";
1568 opendir(DIRHANDLE, $dir);
1569 foreach my $name (sort readdir(DIRHANDLE))
1571 if ($name =~ /\.cpp$/)
1573 open (CPP, "<$dir/$name") or die("Can't open $dir/$name to scan it! oh bugger");
1575 while (defined(my $line = <CPP>))
1578 if ($line =~ /\/\* \$Core: (\w+) \*\//i)
1580 $filelist{$name} = $1;
1582 elsif ($line =~ /\/\* \$ExtraDeps: (.*?) \*\//i)
1584 $specialdeps{$name} = $1;
1586 elsif ($line =~ /\/\* \$ExtraObjects: (.*?) \*\//i)
1588 $extraobjects{$name} = $1;
1590 elsif ($line =~ /\/\* \$ExtraBuild: (.*?) \*\//i)
1592 $extrabuildlines{$name} = $1;
1594 elsif ($line =~ /\/\* \$ExtraSources: (.*?) \*\//i)
1596 $extrasources{$name} = $1;
1598 elsif ($line =~ /\/\* \$If: (\w+) \*\//i)
1600 if (defined $config{$1})
1602 if (($config{$1} !~ /y/i) and ($config{$1} ne "1"))
1605 while (defined($line = <CPP>))
1608 die ("\$If buildsystem instruction within another \$If in file $dir/$name") if ($line =~ /\/\* \$If: (\w+) \*\//i);
1609 last if ($line =~ /\/\* \$EndIf \*\//i);
1614 elsif ($line =~ /\/\* \$Install: (.*?) \*\//i)
1616 if (!exists($existing_install_list{$1}))
1618 $existing_install_list{$1} = 1;
1619 my $idir = (split(' ',$1))[1];
1620 my $ifile = (split(' ',$1))[0];
1621 $install_list = $install_list . " -install -m \$(INSTMODE) $1\n";
1622 $ifile =~ s/.*\///g;
1623 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1626 elsif ($line =~ /\/\* \$CopyInstall: (.*?) \*\//i)
1628 if (!exists($existing_install_list{$1}))
1630 $existing_install_list{$1} = 1;
1631 my $idir = (split(' ',$1))[1];
1632 my $ifile = (split(' ',$1))[0];
1633 $install_list = $install_list . " -cp $1\n";
1634 $ifile =~ s/.*\///g;
1635 $uninstall_list = $uninstall_list . " -rm $idir/$ifile\n";
1642 closedir(DIRHANDLE);
1646 my $freebsd4libs = (defined $config{CRAQ} ? $config{CRAQ} : "");
1649 my $all_libsonly = "";
1650 my $libraryext = "";
1654 if ($config{IS_DARWIN} eq "YES")
1656 $libraryext = "dylib";
1657 $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 "
1662 $RPATH = "-Wl,--rpath -Wl,$config{LIBRARY_DIR}" unless defined $opt_disablerpath;
1663 $othercrap = " \@../make/run-cc.pl \$(CC) -pipe -I../include $RPATH \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1666 foreach my $cpp (sort keys %filelist)
1668 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1669 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1670 $install_list = $install_list . " -install -m \$(INSTMODE) src/" . $filelist{$cpp} . "." . $libraryext . " \$(LIBPATH)\n";
1671 $uninstall_list = $uninstall_list . " -rm \$(LIBPATH)/" . $filelist{$cpp} . "." . $libraryext . "\n";
1673 $all = $all . "moo inspircd\n";
1675 $othercrap = $othercrap . " $all_libsonly\n\n";
1677 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1680 CC = im a cheezeball
1681 CXXFLAGS = -I../include \${FLAGS}
1682 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1683 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1687 print FH "$all\n\n";
1689 my $deps = calcdeps("src/inspircd.cpp");
1690 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1691 print FH "$othercrap\n";
1693 foreach my $cpp (sort keys %filelist)
1695 my $thislib = $filelist{$cpp} . "." . $libraryext;
1699 $objs =~ s/\.cpp$/.o/;
1700 if (exists($extraobjects{$cpp}))
1702 $objs = $objs . " " . $extraobjects{$cpp};
1704 if (exists($extrasources{$cpp}))
1706 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1708 if ($config{IS_DARWIN} eq "YES")
1710 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1714 if (defined $opt_disablerpath)
1716 $libcrap = " -shared";
1720 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1723 $deps = calcdeps("src/$cpp");
1724 if (exists($extrasources{$cpp}))
1726 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1728 my $d = calcdeps("src/$extrasources{$cpp}") . " ";
1731 $deps = $deps . $d . " ";
1735 print FH $thislib . ": $cpp $deps ". (defined($specialdeps{$cpp}) ? $specialdeps{$cpp} : "") . "\n";
1736 print FH " \@../make/run-cc.pl \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1737 if (exists($extrabuildlines{$cpp}))
1739 print FH " " . $extrabuildlines{$cpp} . "\n";
1741 print FH " \@../make/run-cc.pl \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1744 print FH "moo:\n \@\${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1746 # close main makefile
1750 # generate a list of .so
1751 foreach my $cmd (@cmdlist) {
1752 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1755 # and now reopen the commands makefile
1756 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1759 CXXFLAGS = -I../../include \${FLAGS}
1766 # now print the command file details.
1767 foreach my $cmd (@cmdlist) {
1769 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
1770 \@../../make/run-cc.pl \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so cmd_$cmd.cpp
1776 # Routine to list out the extra/ modules that have been enabled.
1777 # Note: when getting any filenames out and comparing, it's important to lc it if the
1778 # file system is not case-sensitive (== Epoc, MacOS, OS/2 (incl DOS/DJGPP), VMS, Win32
1779 # (incl NetWare, Symbian)). Cygwin may or may not be case-sensitive, depending on
1780 # configuration, however, File::Spec does not currently tell us (it assumes Unix behavior).
1781 sub list_extras () {
1784 my $srcdir = File::Spec->catdir("src", "modules");
1785 my $abs_srcdir = File::Spec->rel2abs($srcdir);
1788 opendir $dd, File::Spec->catdir($abs_srcdir, "extra") or die (File::Spec->catdir($abs_srcdir, "extra") . ": $!\n");
1789 my @extras = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1792 opendir $dd, $abs_srcdir or die "$abs_srcdir: $!\n";
1793 my @sources = map { File::Spec->case_tolerant() ? lc($_) : $_ } (readdir($dd));
1796 my $maxlen = (sort { $b <=> $a } (map {length($_)} (@extras)))[0];
1798 EXTRA: for my $extra (@extras) {
1799 next if (File::Spec->curdir() eq $extra || File::Spec->updir() eq $extra);
1800 next if ($extra eq '.svn');
1801 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1802 my $abs_source = File::Spec->catfile($abs_srcdir, $extra);
1803 next unless ($extra =~ m/\.(cpp|h)$/ || (-d $abs_extra)); # C++ Source/Header, or directory
1804 if (-l $abs_source) {
1805 # Symlink, is it in the right place?
1806 my $targ = readlink($abs_source);
1807 my $abs_targ = File::Spec->rel2abs($targ, $abs_srcdir);
1808 if ($abs_targ eq $abs_extra) {
1809 $extras{$extra} = "\e[32;1menabled\e[0m";
1811 $extras{$extra} = sprintf("\e[31;1mwrong symlink target (%s)\e[0m", $abs_targ);
1813 } elsif (-e $abs_source) {
1814 my ($devext, $inoext) = stat($abs_extra);
1815 my ($devsrc, $inosrc, undef, $lnksrc) = stat($abs_source);
1817 if ($devsrc == $devext && $inosrc == $inoext) {
1818 $extras{$extra} = "\e[32;1menabled\e[0m";
1820 $extras{$extra} = sprintf("\e[31;1mwrong hardlink target (%d:%d)\e[0m", $devsrc, $inosrc);
1823 open my $extfd, "<", $abs_extra;
1824 open my $srcfd, "<", $abs_source;
1826 if (scalar(<$extfd>) eq scalar(<$srcfd>)) {
1827 $extras{$extra} = "\e[32;1menabled\e[0m";
1829 $extras{$extra} = sprintf("\e[31;1mout of synch (re-copy)\e[0m");
1833 $extras{$extra} = "\e[33;1mdisabled\e[0m";
1836 # Now let's add dependency info
1837 for my $extra (keys(%extras)) {
1838 next unless $extras{$extra} =~ m/enabled/; # only process enabled extras.
1839 my $abs_extra = File::Spec->catfile($abs_srcdir, "extra", $extra);
1840 my @deps = split / +/, getdependencies($abs_extra);
1841 for my $dep (@deps) {
1842 if (exists($extras{$dep})) {
1843 my $ref = \$extras{$dep}; # Take reference.
1844 if ($$ref !~ m/needed by/) {
1845 # First dependency found.
1846 if ($$ref =~ m/enabled/) {
1847 $$ref .= " (needed by \e[32;1m$extra\e[0m";
1849 $$ref =~ s/\e\[.*?m//g; # Strip out previous coloring. Will be set in bold+red+blink later.
1850 $$ref .= " (needed by \e[0;32;1;5m$extra\e[0;31;1;5m";
1853 if ($$ref =~ m/enabled/) {
1854 $$ref .= ", \e[32;1m$extra\e[0m";
1856 $$ref .= ", \e[0;32;1;5m$extra\e[0;31;1;5m";
1862 for my $extra (sort {$a cmp $b} keys(%extras)) {
1863 my $text = $extras{$extra};
1864 if ($text =~ m/needed by/ && $text !~ m/enabled/) {
1865 printf "\e[31;1;5m%-*s = %s%s\e[0m\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? ")" : "");
1867 printf "%-*s = %s%s\n", $maxlen, $extra, $text, ($text =~ m/needed by/ ? "\e[0m)" : "");
1870 return keys(%extras) if wantarray; # Can be used by manage_extras.
1873 sub enable_extras (@) {
1875 for my $extra (@extras) {
1876 my $extrapath = "src/modules/extra/$extra";
1877 if (!-e $extrapath) {
1878 print STDERR "Cannot enable \e[32;1m$extra\e[0m : No such file or directory in src/modules/extra\n";
1881 my $source = "src/modules/$extra";
1883 print STDERR "Cannot enable \e[32;1m$extra\e[0m : destination in src/modules exists (might already be enabled?)\n";
1886 # Get dependencies, and add them to be processed.
1887 my @deps = split / +/, getdependencies($extrapath);
1888 for my $dep (@deps) {
1889 next if scalar(grep { $_ eq $dep } (@extras)) > 0; # Skip if we're going to be enabling it anyway.
1890 if (!-e "src/modules/$dep") {
1891 if (-e "src/modules/extra/$dep") {
1892 print STDERR "Will also enable extra \e[32;1m$dep\e[0m (needed by \e[32;1m$extra\e[0m)\n";
1895 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";
1899 print "Enabling $extra ... \n";
1900 symlink "extra/$extra", $source or print STDERR "$source: Cannot link to 'extra/$extra': $!\n";
1904 sub disable_extras (@)
1906 opendir my $dd, "src/modules/extra/";
1907 my @files = readdir($dd);
1910 EXTRA: for my $extra (@extras) {
1911 my $extrapath = "src/modules/extra/$extra";
1912 my $source = "src/modules/$extra";
1913 if (!-e $extrapath) {
1914 print STDERR "Cannot disable \e[32;1m$extra\e[0m : Is not an extra\n";
1917 if ((! -l $source) || readlink($source) ne "extra/$extra") {
1918 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";
1921 # Check if anything needs this.
1922 for my $file (@files) {
1923 my @deps = split / +/, getdependencies("src/modules/extra/$file");
1924 # File depends on this extra...
1925 if (scalar(grep { $_ eq $extra } @deps) > 0) {
1926 # And is both enabled and not about to be disabled.
1927 if (-e "src/modules/$file" && scalar(grep { $_ eq $file } @extras) < 1) {
1928 print STDERR "Cannot disable \e[32;1m$extra\e[0m : is needed by \e[32;1m$file\e[0m\n";
1934 print "Disabling $extra ... \n";
1935 unlink "src/modules/$extra" or print STDERR "Cannot disable \e[32;1m$extra\e[0m : $!\n";