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 # Utility functions for our buildsystem
24 use make::opensslcert;
27 "channels.cpp" => "libIRCDchannels",
28 "mode.cpp" => "libIRCDmode",
29 "xline.cpp" => "libIRCDxline",
30 "inspstring.cpp"=> "libIRCDstring",
31 "dns.cpp" => "libIRCDasyncdns",
32 "base.cpp" => "libIRCDbase",
33 "configreader.cpp"=> "libIRCDconfigreader",
34 "inspsocket.cpp"=> "libIRCDinspsocket",
35 "commands.cpp" => "libIRCDcommands",
36 "dynamic.cpp" => "libIRCDdynamic",
37 "users.cpp" => "libIRCDusers",
38 "modules.cpp" => "libIRCDmodules",
39 "wildcard.cpp" => "libIRCDwildcard",
40 "helperfuncs.cpp"=> "libIRCDhelper",
41 "hashcomp.cpp" => "libIRCDhash",
42 "socket.cpp" => "libIRCDsocket",
43 "socketengine.cpp"=> "libIRCDsocketengine",
44 "userprocess.cpp"=> "libIRCDuserprocess",
45 "cull_list.cpp"=> "libIRCDcull_list",
46 "command_parse.cpp"=> "libIRCDcommand_parse",
47 "timer.cpp" => "libIRCDtimer",
48 "snomasks.cpp" => "libIRCDsnomasks",
49 "server.cpp" => "libIRCDserver",
50 "filelogger.cpp"=> "libIRCDfilelogger",
51 "user_resolver.cpp"=> "libIRCDuserresolver",
55 "mode.cpp" => "\$(RELCPPFILES)",
58 my %extrabuildlines = (
59 "mode.cpp" => "\${MAKE} -C \"modes\" DIRNAME=\"src/modes\" CC=\"\$(CC)\" \$(MAKEARGS) CPPFILES=\"\$(CPPFILES)\"",
63 "mode.cpp" => "modes/modeclasses.a"
70 "inspircd_win32wrapper.h",
79 'enable-gnutls' => \$opt_use_gnutls,
80 'rebuild' => \$opt_rebuild,
81 'enable-openssl' => \$opt_use_openssl,
82 'disable-interactive' => \$opt_nointeractive,
83 'with-nick-length=i' => \$opt_nick_length,
84 'with-channel-length=i' => \$opt_chan_length,
85 'with-max-clients=i' => \$opt_maxclients,
86 'enable-ports' => \$opt_ports,
87 'enable-epoll' => \$opt_epoll,
88 'enable-kqueue' => \$opt_kqueue,
89 'disable-ports' => \$opt_noports,
90 'disable-epoll' => \$opt_noepoll,
91 'disable-kqueue' => \$opt_nokqueue,
92 'enable-ipv6' => \$opt_ipv6,
93 'enable-remote-ipv6' => \$opt_ipv6links,
94 'disable-remote-ipv6' => \$opt_noipv6links,
95 'with-cc=s' => \$opt_cc,
96 'with-ident-length=i' => \$opt_ident,
97 'with-quit-length=i' => \$opt_quit,
98 'with-topic-length=i' => \$opt_topic,
99 'with-maxbuf=i' => \$opt_maxbuf,
100 'with-kick-length=i' => \$opt_kick,
101 'with-gecos-length=i' => \$opt_gecos,
102 'with-away-length=i' => \$opt_away,
103 'with-max-modes=i' => \$opt_modes,
104 'prefix=s' => \$opt_base_dir,
105 'config-dir=s' => \$opt_config_dir,
106 'module-dir=s' => \$opt_module_dir,
107 'binary-dir=s' => \$opt_binary_dir,
108 'library-dir=s' => \$opt_library_dir,
109 'disable-debuginfo' => sub { $opt_disable_debug = 1 },
110 'help' => sub { showhelp(); },
111 'modupdate' => sub { modupdate(); },
112 'update' => sub { update(); },
113 'svnupdate' => sub { svnupdate(); },
114 'clean' => sub { clean(); },
117 my $non_interactive = (
118 (defined $opt_library_dir) ||
119 (defined $opt_base_dir) ||
120 (defined $opt_config_dir) ||
121 (defined $opt_module_dir) ||
122 (defined $opt_base_dir) ||
123 (defined $opt_binary_dir) ||
124 (defined $opt_nointeractive) ||
125 (defined $opt_away) ||
126 (defined $opt_gecos) ||
127 (defined $opt_kick) ||
128 (defined $opt_maxclients) ||
129 (defined $opt_modes) ||
130 (defined $opt_topic) ||
131 (defined $opt_quit) ||
132 (defined $opt_ident) ||
134 (defined $opt_ipv6) ||
135 (defined $opt_ipv6links) ||
136 (defined $opt_noipv6links) ||
137 (defined $opt_kqueue) ||
138 (defined $opt_epoll) ||
139 (defined $opt_ports) ||
140 (defined $opt_maxchans) ||
141 (defined $opt_opermaxchans) ||
142 (defined $opt_chan_length) ||
143 (defined $opt_nick_length) ||
144 (defined $opt_use_openssl) ||
145 (defined $opt_nokqueue) ||
146 (defined $opt_noepoll) ||
147 (defined $opt_noports) ||
148 (defined $opt_maxbuf) ||
149 (defined $opt_use_gnutls)
151 my $interactive = !$non_interactive;
154 chomp($topdir = getcwd());
155 $this = resolve_directory($topdir); # PWD, Regardless.
156 @modlist = (); # Declare for Module List..
157 %config = (); # Initiate Configuration Hash..
158 $config{ME} = resolve_directory($topdir); # Present Working Directory
160 $config{BASE_DIR} = $config{ME};
162 if (defined $opt_base_dir)
164 $config{BASE_DIR} = $opt_base_dir;
167 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
168 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
169 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
170 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
172 if (defined $opt_config_dir)
174 $config{CONFIG_DIR} = $opt_config_dir;
176 if (defined $opt_module_dir)
178 $config{MODULE_DIR} = $opt_module_dir;
180 if (defined $opt_binary_dir)
182 $config{BINARY_DIR} = $opt_binary_dir;
184 if (defined $opt_library_dir)
186 $config{LIBRARY_DIR} = $opt_library_dir;
188 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
189 chomp($config{HAS_OPENSSL} = `pkg-config --modversion openssl 2>/dev/null`); # Openssl version
190 chomp($gnutls_ver = $config{HAS_GNUTLS});
191 chomp($openssl_ver = $config{HAS_OPENSSL});
192 $config{USE_GNUTLS} = "n";
193 if (defined $opt_use_gnutls)
195 $config{USE_GNUTLS} = "y"; # Use gnutls.
197 $config{USE_OPENSSL} = "n"; # Use openssl.
198 if (defined $opt_use_openssl)
200 $config{USE_OPENSSL} = "y";
203 # no, let's not change these.
204 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
205 if (!defined $opt_disable_debug)
207 $config{OPTIMISATI} = "-g1"; # Optimisation Flag
211 $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF!
214 $config{NICK_LENGT} = "31"; # Default Nick Length
215 if (defined $opt_nick_length)
217 $config{NICK_LENGT} = $opt_nick_length;
219 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
220 if (defined $opt_chan_length)
222 $config{CHAN_LENGT} = $opt_chan_length;
224 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
225 if (defined $opt_modes)
227 $config{MAXI_MODES} = $opt_modes;
229 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
230 $config{HAS_STDINT} = "false"; # stdint.h check
231 $config{USE_KQUEUE} = "y"; # kqueue enabled
232 if (defined $opt_kqueue)
234 $config{USE_KQUEUE} = "y";
236 if (defined $opt_nokqueue)
238 $config{USE_KQUEUE} = "n";
240 $config{USE_EPOLL} = "y"; # epoll enabled
241 if (defined $opt_epoll)
243 $config{USE_EPOLL} = "y";
245 if (defined $opt_noepoll)
247 $config{USE_EPOLL} = "n";
249 $config{USE_PORTS} = "y"; # epoll enabled
250 if (defined $opt_ports)
252 $config{USE_PORTS} = "y";
254 if (defined $opt_noports)
256 $config{USE_PORTS} = "n";
258 $config{IPV6} = "n"; # IPv6 support (experimental)
259 if (defined $opt_ipv6)
263 $config{SUPPORT_IP6LINKS} = "y"; # IPv4 supporting IPv6 links (experimental)
264 if (defined $opt_ipv6links)
266 $config{SUPPORT_IP6LINKS} = "y";
268 if (defined $opt_noipv6links)
270 $config{SUPPORT_IP6LINKS} = "n";
272 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit
273 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`); # Hard FD Limit
274 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
275 $config{_SOMAXCONN} = SOMAXCONN; # Max connections in accept queue
276 $config{OSNAME} = $^O; # Operating System Name
277 $config{IS_DARWIN} = "NO"; # Is OSX?
278 $config{STARTSCRIPT} = "inspircd"; # start script?
279 $config{DESTINATION} = "BASE"; # Is target path.
280 $config{EXTRA_DIR} = ""; # Is empty.
281 if ($config{OSNAME} =~ /darwin/i)
283 $config{IS_DARWIN} = "YES";
284 $config{STARTSCRIPT} = "org.inspircd.plist"; # start script for OSX.
285 $config{DESTINATION} = "LAUNCHDPATH"; # Is OSX target.
286 $config{EXTRA_DIR} = " launchd_dir"; # Is OSX specific path.
288 $config{CC} = "g++"; # C++ compiler
291 $config{CC} = $opt_cc;
293 $exec = $config{CC} . " -dumpversion | cut -c 1";
294 chomp($config{GCCVER} = `$exec`); # Major GCC Version
295 $config{MAKEORDER} = "ircd mods"; # build order
296 $config{MAX_IDENT} = "12"; # max ident size
297 $config{MAX_QUIT} = "255"; # max quit message size
298 $config{MAX_TOPIC} = "307"; # max topic size
299 $config{MAX_KICK} = "255"; # max kick message size
300 $config{MAX_GECOS} = "128"; # max GECOS size
301 $config{MAX_AWAY} = "200"; # max AWAY size
302 $config{MAXBUF} = "512"; # Max buffer size
303 if (defined $opt_ident)
305 $config{MAX_IDENT} = $opt_ident;
307 if (defined $opt_quit)
309 $config{MAX_QUIT} = $opt_quit;
311 if (defined $opt_topic)
313 $config{MAX_TOPIC} = $opt_topic;
315 if (defined $opt_kick)
317 $config{MAX_KICK} = $opt_kick;
319 if (defined $opt_gecos)
321 $config{MAX_GECOS} = $opt_gecos;
323 if (defined $opt_away)
325 $config{MAX_AWAY} = $opt_away;
328 $config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/;
329 $config{HAS_OPENSSL} = $1;
331 if ($config{GCCVER} eq "") {
332 print $config{CC} . " was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
336 if (!$config{MAX_CLIENT_T}) {
337 $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default'
338 $fd_scan_fail = "true"; # Used Later
341 # Get and Set some important vars..
346 system("rm -rf .config.cache");
352 chomp($topdir = getcwd());
353 $this = resolve_directory($topdir); # PWD, Regardless.
355 # Does the cache file exist?
357 # No, No it doesn't.. *BASH*
358 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
361 # We've Loaded the cache file and all our variables..
362 print "Updating Files..\n";
364 if ($opt_disable_debug == 1)
366 print "Disabling debug information (-g).\n";
367 $config{OPTIMISATI} = "";
370 $has_epoll = $config{HAS_EPOLL};
371 $has_ports = $config{HAS_PORTS};
372 $has_kqueue = $config{HAS_KQUEUE};
381 print "Configure update failed: $@\n";
389 chomp($topdir = getcwd());
390 $this = resolve_directory($topdir); # PWD, Regardless.
392 # Does the cache file exist?
394 # No, No it doesn't.. *BASH*
395 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
398 # We've Loaded the cache file and all our variables..
399 print "Updating Files..\n";
401 $has_epoll = $config{HAS_EPOLL};
402 $has_ports = $config{HAS_PORTS};
403 $has_kqueue = $config{HAS_KQUEUE};
412 print "Module update failed: $@\n";
422 open(FH,"<.svn/entries") or $fail = 1;
424 print "This is not an SVN copy of InspIRCd.\n";
431 system("svn update");
432 system("perl configure -update");
433 if (defined $opt_rebuild) {
434 system("make install");
439 print "Running non-interactive configure...\n" unless $interactive;
440 print "Checking for cache from previous configure... ";
441 print ((!getcache()) ? "not found\n" : "found\n");
442 print "Checking operating system version... ";
443 print getosflags() . "\n";
445 if (defined $opt_maxclients)
447 $config{MAX_CLIENT} = $opt_maxclients;
450 if (!$config{MAX_CLIENT}) {
451 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
452 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
453 # higher than the found value" :))
454 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
457 printf "Checking if stdint.h exists... ";
458 $config{HAS_STDINT} = "true";
460 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
461 if ($config{HAS_STDINT} eq "true") {
464 print "yes\n" if $config{HAS_STDINT} eq "true";
465 print "no\n" if $config{HAS_STDINT} eq "false";
468 printf "Checking if strlcpy exists... ";
469 # Perform the strlcpy() test..
470 $config{HAS_STRLCPY} = "false";
472 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
474 while (chomp($line = <STRLCPY>)) {
475 # try and find the delcaration of:
476 # size_t strlcpy(...)
477 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
478 $config{HAS_STRLCPY} = "true";
483 print "yes\n" if $config{HAS_STRLCPY} eq "true";
484 print "no\n" if $config{HAS_STRLCPY} eq "false";
487 printf "Checking if kqueue exists... ";
490 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
492 while (chomp($line = <KQUEUE>)) {
493 # try and find the delcaration of:
495 if ($line =~ /int(\0x9|\s)+kqueue/) {
501 print "yes\n" if $has_kqueue == 1;
502 print "no\n" if $has_kqueue == 0;
504 printf "Checking if epoll exists... ";
507 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
513 my $kernel = `uname -r`;
515 if (($kernel =~ /^2\.0\./) || ($kernel =~ /^2\.2\./) || ($kernel =~ /^2\.4\./)) {
520 # Suggestion from nenolod, weed out odd systems which have glibc built
521 # against 2.4 kernels (ick)
522 my $kernel_arch = `uname -p`;
526 if ($kernel_arch =~ /x86_64/) {
527 open (FH,"/lib64/libc.so.6|") or $has_epoll = 0;
530 open (FH,"/lib/libc.so.6|") or $has_epoll = 0;
534 while (chomp($line = <FH>))
536 if ($line =~ /GNU C Library .* version (.*?) /)
539 $libcv =~ /(\d+\.\d+)/;
542 elsif ($line =~ /Compiled on a Linux (.*?\..*?)\.* system/)
545 # Fix for some retarded libc builds, strip off >> and << etc.
546 $kernelv =~ /(\d+\.\d+)/;
554 printf "libc too old: $libcv... ";
559 printf "libc built against older kernel $kernelv... ";
564 print "yes\n" if $has_epoll == 1;
565 print "no\n" if $has_epoll == 0;
567 printf "Checking if Solaris I/O completion ports are available... ";
569 my $system = `uname -s`;
571 $has_ports = 1 if ($system eq "SunOS");
574 my $kernel = `uname -r`;
576 if (($kernel !~ /^5\.1./)) {
580 print "yes\n" if $has_ports == 1;
581 print "no\n" if $has_ports == 0;
583 $config{HAS_EPOLL} = $has_epoll;
584 $config{HAS_KQUEUE} = $has_kqueue;
586 printf "Checking for libgnutls... ";
587 if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) {
589 $config{HAS_GNUTLS} = "y";
592 $config{HAS_GNUTLS} = "n";
595 printf "Checking for openssl... ";
596 if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) {
598 $config{HAS_OPENSSL} = "y";
601 $config{HAS_OPENSSL} = "n";
604 printf "Checking if you are running an ancient, unsupported OS... ";
605 if ($config{OSNAME} =~ /FreeBSD/i)
607 $version = `uname -r`;
608 if ($version =~ /^4\./)
610 $foundit = `ls -l /usr/local/lib/libgnugetopt* | wc -l`;
613 # ICKY ICKY ICK, FREEBSD 4.x! GET AN UPGRADE!
614 $config{CRAQ} = "-L/usr/local/lib -lgnugetopt -DHAVE_DECL_GETOPT=1";
619 print "\n\nERROR: You require libgnugetopt (from ports or packages) to build InspIRCd on FreeBSD 4.11.\n";
625 print "no ($version)\n";
631 print "no ($config{OSNAME})\n";
634 ################################################################################
635 # BEGIN INTERACTIVE PART #
636 ################################################################################
644 my $rev = getrevision();
645 # Display Introduction Message..
647 Welcome to the \033[1mInspIRCd\033[0m Configuration program! (\033[1minteractive mode\033[0m)
648 \033[1mPackage maintainers: Type ./configure --help for non-interactive help\033[0m
650 *** If you are unsure of any of these values, leave it blank for ***
651 *** standard settings that will work, and your server will run ***
652 *** using them. Please consult your IRC network admin if in doubt. ***
654 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
655 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
656 dir, otherwise you won't have a config file!
658 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos)
659 Maximum file descriptors: \033[1;32m$config{MAX_CLIENT_T}\033[0m
660 Your InspIRCd revision ID is \033[1;32mr$rev\033[0m";
662 print " (Non-SVN build)";
666 $config{CHANGE_COMPILER} = "n";
667 print "I have detected the following compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
669 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
670 print "\033[1;32mIMPORTANT!\033[0m A GCC 2.x compiler has been detected, and
671 should NOT be used. You should probably specify a newer compiler.\n\n";
672 yesno(CHANGE_COMPILER,"Do you want to change the compiler?");
673 if ($config{CHANGE_COMPILER} =~ /y/i) {
674 print "What command do you want to use to invoke your compiler?\n";
675 print "[\033[1;32m$config{CC}\033[0m] -> ";
676 chomp($config{CC} = <STDIN>);
677 if ($config{CC} eq "") {
680 chomp($foo = `$config{CC} -dumpversion | cut -c 1`);
682 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
683 print "Queried compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
684 if ($config{GCCVER} < 3) {
685 print "\033[1;32mGCC 2.x WILL NOT WORK!\033[0m. Let's try that again, shall we?\n";
689 print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n";
696 # Directory Settings..
697 my $tmpbase = $config{BASE_DIR};
698 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
699 if ($tmpbase ne $config{BASE_DIR}) {
700 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Dir
701 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
702 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
703 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
706 dir_check("are the configuration files", "CONFIG_DIR");
707 dir_check("are the modules to be compiled to", "MODULE_DIR");
708 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
709 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
712 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?");
716 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?");
720 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?");
723 $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y") || ($config{USE_PORTS} eq "y"));
724 if (!$chose_hiperf) {
725 print "No high-performance socket engines are available, or you chose\n";
726 print "not to enable one. Defaulting to select() engine.\n\n";
729 yesno(IPV6,"Would you like to build InspIRCd with IPv6 support?");
732 if ($config{IPV6} eq "y") {
733 print "You have chosen to build an \033[1;32mIPV6-enabled\033[0m server.\nTo accept IPV4 users, you can still use IPV4 addresses\nin your port bindings..\n\n";
734 $config{SUPPORT_IP6LINKS} = "y";
736 yesno(SUPPORT_IP6LINKS,"You have chosen to build an \033[1;32mIPV4-only\033[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)");
740 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
741 print "I have detected both \033[1;32mGnuTLS\033[0m and \033[1;32mOpenSSL\033[0m on your system.\n";
742 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
743 print "instead, you should enable the OpenSSL module yourself\n";
744 print "by copying it from src/modules/extra to src/modules.\n\n";
745 print "Detected GnuTLS version: \033[1;32m" . $gnutls_ver . "\033[0m\n";
746 print "Detected OpenSSL version: \033[1;32m" . $openssl_ver . "\033[0m\n\n";
749 if ($config{HAS_GNUTLS} eq "y") {
750 yesno(USE_GNUTLS, "Would you like to enable SSL Support?");
751 if ($config{USE_GNUTLS} eq "y") {
752 print "\nUsing GnuTLS SSL module.\n";
754 } elsif ($config{HAS_OPENSSL} eq "y") {
755 yesno(USE_OPENSSL, "Would you like to enable SSL Support?");
756 if ($config{USE_OPENSSL} eq "y") {
757 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
761 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";
764 print "\nThe following questions will ask you for various figures relating\n";
765 print "To your IRCd install. Please note that these should usually be left\n";
766 print "as defaults unless you have a real reason to change them. If they\n";
767 print "changed, then the values must be identical on all servers on your\n";
768 print "network, or malfunctions and/or crashes may occur, with the exception\n";
769 print "of the 'maximum number of clients' setting which may be different on\n";
770 print "different servers on the network.\n\n";
772 # File Descriptor Settings..
773 promptnumeric("number of clients at any one time", "MAX_CLIENT_T");
774 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
775 $config{MAX_DESCRIPTORS} = $config{MAX_CLIENT_T};
777 promptnumeric("length of nicknames", "NICK_LENGT");
778 promptnumeric("length of channel names", "CHAN_LENGT");
779 promptnumeric("number of mode changes in one line", "MAXI_MODES");
780 promptnumeric("length of an ident (username)", "MAX_IDENT");
781 promptnumeric("length of a quit message", "MAX_QUIT");
782 promptnumeric("length of a channel topic", "MAX_TOPIC");
783 promptnumeric("length of a kick message", "MAX_KICK");
784 promptnumeric("length of a GECOS (real name)", "MAX_GECOS");
785 promptnumeric("length of an away message", "MAX_AWAY");
790 if (($config{USE_GNUTLS} eq "y") && ($config{HAS_GNUTLS} ne "y"))
792 print "Sorry, but i couldn't detect gnutls. Make sure gnutls-config is in your path.\n";
795 if (($config{USE_OPENSSL} eq "y") && ($config{HAS_OPENSSL} ne "y"))
797 print "Sorry, but i couldn't detect openssl. Make sure openssl is in your path.\n";
801 if ($config{USE_GNUTLS} eq "y") {
803 open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
806 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
807 chdir("src/modules");
808 system("ln -s extra/m_ssl_gnutls.cpp");
815 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
817 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
820 print "SSL Certificates Not found, Generating.. \n\n
821 *************************************************************
822 * Generating the Private Key may take some time, go grab a *
823 * Coffee. Even better, to generate some more entropy if it *
824 * is taking a while, open another console and type du / a *
825 * few times and get that HD going :) Then answer the *
826 * Questions which follow. If you are unsure, just hit enter *
827 *************************************************************\n\n";
828 $failed = make_gnutls_cert();
830 print "\n\033[1;32mCertificate generation failed!\033[0m\n\n";
832 print "\nCertificate generation complete, copying to config directory... ";
833 system("mv key.pem $config{CONFIG_DIR}/key.pem");
834 system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
839 print "SSL Certificates found, skipping.\n\n";
844 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
846 } elsif ($config{USE_OPENSSL} eq "y") {
848 open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
851 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
852 chdir("src/modules");
853 system("ln -s extra/m_ssl_openssl.cpp");
860 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
862 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
865 print "SSL Certificates Not found, Generating.. \n\n
866 *************************************************************
867 * Generating the certificates may take some time, go grab a *
868 * coffee, or something. *
869 *************************************************************\n\n";
871 print "\nCertificate generation complete, copying to config directory... ";
872 system("mv key.pem $config{CONFIG_DIR}/key.pem");
873 system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
874 system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
877 print "SSL Certificates found, skipping.\n\n"
882 print "Skipping SSL certificate generation\nin non-interactive mode.\n\n";
885 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
886 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
894 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
895 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
896 print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
897 print "load the required modules in your config. This configure process\n";
898 print "has just prepared these modules to be compiled for you, and has not\n";
899 print "configured them to be compiled into the core of the ircd.\n";
901 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
902 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
903 print "\033[1;32mWARNING!\033[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";
906 if ($config{GCCVER} < "3") {
908 \033[1;32mWARNING!\033[0m You are attempting to compile InspIRCd on GCC 2.x!
909 GCC 2.x series compilers only had partial (read as broken) C++ support, and
910 your compile will most likely fail horribly! If you have any problems, do NOT
911 report them to the bugtracker or forums without first upgrading your compiler
912 to a newer 3.x or 4.x (or whatever is available currently) version.
916 ################################################################################
918 ################################################################################
920 # Retrieves the .config.cache file, and loads values into the main config hash.
921 open(CACHE, ".config.cache") or return 0;
924 # Ignore Blank lines, and comments..
927 my ($key, $value) = split("=", $_, 2);
928 $value =~ /^\"(.*)\"$/;
929 # Do something with data here!
937 # Dump the contents of %config
938 print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
939 open(FILEHANDLE, ">.config.cache");
940 foreach $key (keys %config) {
941 print FILEHANDLE "$key=\"$config{$key}\"\n";
947 my ($desc, $hash_key) = @_;
950 print "In what directory $desc?\n";
951 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
952 chomp($var = <STDIN>);
954 $var = $config{$hash_key};
956 if ($var =~ /^\~\/(.+)$/) {
957 # Convert it to a full path..
958 $var = resolve_directory($ENV{HOME} . "/" . $1);
960 elsif ((($config{OSNAME} =~ /MINGW32/i) and ($var !~ /^[A-Z]{1}:\\.*/)) and (substr($var,0,1) ne "/"))
962 # Assume relative Path was given.. fill in the rest.
963 $var = $this . "/$var";
966 $var = resolve_directory($var);
968 print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
969 chomp($tmp = <STDIN>);
970 if (($tmp eq "") || ($tmp =~ /^y/i)) {
971 # Attempt to Create the Dir..
973 system("mkdir -p \"$var\" >> /dev/null 2>&1");
974 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
976 print "Unable to create directory. ($var)\n\n";
981 # They said they don't want to create, and we can't install there.
987 # Target exists, but is not a directory.
988 print "File $var exists, but is not a directory.\n\n";
992 # Either Dir Exists, or was created fine.
993 $config{$hash_key} = $var;
1001 $config{LDLIBS} = "-lstdc++";
1002 $config{FLAGS} = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual -Wno-deprecated $config{OPTIMISATI}";
1003 $config{DEVELOPER} = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual -Wno-deprecated -g";
1004 $SHARED = "-Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared";
1005 $config{MAKEPROG} = "make";
1007 if ($config{OSNAME} =~ /darwin/i) {
1008 $config{FLAGS} = "-DDARWIN -frtti -fPIC -Wall -Woverloaded-virtual -Wno-deprecated $config{OPTIMISATI}";
1009 $SHARED = "-bundle -twolevel_namespace -undefined dynamic_lookup";
1010 $config{LDLIBS} = "-ldl -lstdc++";
1013 if ($config{OSNAME} =~ /OpenBSD/i) {
1014 $config{MAKEPROG} = "gmake";
1015 $config{LDLIBS} = $config{LDLIBS} . " -lunwind";
1016 chomp($foo = `eg++ -dumpversion | cut -c 1`);
1017 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
1018 # if theyre not running this, configure lets the build continue but they probably wont manage to
1019 # compile as this standard version is 2.95.3!
1021 $config{CC} = "eg++";
1022 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
1027 if ($config{OSNAME} =~ /Linux/i) {
1028 $config{LDLIBS} = "-ldl -lstdc++";
1029 $config{FLAGS} = "-fno-strict-aliasing -fPIC -Wall -Woverloaded-virtual -Wno-deprecated $config{OPTIMISATI}";
1030 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1031 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1032 $config{MAKEPROG} = "make";
1035 if ($config{OSNAME} =~ /FreeBSD/i) {
1036 $config{FLAGS} .= " " . $ENV{CXXFLAGS} if exists($ENV{CXXFLAGS});
1037 $config{LDLIBS} .= " " . $ENV{LDLIBS} if exists($ENV{LDLIBS});
1040 if ($config{OSNAME} =~ /SunOS/i or $config{OSNAME} =~ /solaris/i)
1042 # solaris/sunos needs these
1043 # socket = bsd sockets api
1045 # rt = POSIX realtime extensions
1046 # resolv = inet_aton only (why isnt this in nsl?!)
1047 $config{MAKEPROG} = "gmake";
1048 $config{LDLIBS} .= " -lsocket -lnsl -lrt -lresolv";
1052 if($config{OSNAME} =~ /MINGW32/i)
1054 # All code is position-independent on windows
1055 $config{FLAGS} =~ s/-fPIC //;
1059 return $config{OSNAME};
1063 my($writeheader) = @_;
1064 # First File.. inspircd_config.h
1065 chomp(my $incos = `uname -n -s -r`);
1066 chomp($version = `sh src/version.sh`);
1067 chomp(my $revision2 = getrevision());
1068 if ($writeheader == 1)
1070 print "Writing \033[1;32minspircd_config.h\033[0m\n";
1071 open(FILEHANDLE, ">include/inspircd_config.h");
1072 my $NL = $config{NICK_LENGT}+1;
1073 my $CL = $config{CHAN_LENGT}+1;
1074 print FILEHANDLE <<EOF;
1075 /* Auto generated by configure, do not modify! */
1076 #ifndef __CONFIGURATION_AUTO__
1077 #define __CONFIGURATION_AUTO__
1079 /* this is for windows support. */
1080 #define CoreExport /**/
1081 #define DllExport /**/
1083 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
1084 #define MOD_PATH "$config{MODULE_DIR}"
1085 #define VERSION "$version"
1086 #define REVISION "$revision2"
1087 #define MAXCLIENTS $config{MAX_CLIENT}
1088 #define MAXCLIENTS_S "$config{MAX_CLIENT}"
1089 #define SOMAXCONN_S "$config{_SOMAXCONN}"
1090 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
1093 #define MAXMODES $config{MAXI_MODES}
1094 #define IDENTMAX $config{MAX_IDENT}
1095 #define MAXQUIT $config{MAX_QUIT}
1096 #define MAXTOPIC $config{MAX_TOPIC}
1097 #define MAXKICK $config{MAX_KICK}
1098 #define MAXGECOS $config{MAX_GECOS}
1099 #define MAXAWAY $config{MAX_AWAY}
1100 #define OPTIMISATION $config{OPTIMITEMP}
1101 #define LIBRARYDIR "$config{LIBRARY_DIR}"
1102 #define SYSTEM "$incos"
1104 print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n";
1106 if ($config{OSNAME} =~ /SunOS/i) {
1107 print FILEHANDLE "#define IS_SOLARIS\n";
1109 if ($config{OSNAME} =~ /MINGW32/i) {
1110 print FILEHANDLE "#define IS_MINGW\n";
1112 if ($config{GCCVER} >= 3) {
1113 print FILEHANDLE "#define GCC3\n";
1115 if ($config{HAS_STRLCPY} eq "true") {
1116 print FILEHANDLE "#define HAS_STRLCPY\n";
1118 if ($config{HAS_STDINT} eq "true") {
1119 print FILEHANDLE "#define HAS_STDINT\n";
1121 if ($config{IPV6} =~ /y/i) {
1122 print FILEHANDLE "#define IPV6\n";
1124 if ($config{SUPPORT_IP6LINKS} =~ /y/i) {
1125 print FILEHANDLE "#define SUPPORT_IP6LINKS\n";
1128 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1129 print FILEHANDLE "#define USE_KQUEUE\n";
1130 $se = "socketengine_kqueue";
1133 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1134 print FILEHANDLE "#define USE_EPOLL\n";
1135 $se = "socketengine_epoll";
1138 if (($has_ports) && ($config{USE_PORTS} eq "y")) {
1139 print FILEHANDLE "#define USE_PORTS\n";
1140 $se = "socketengine_ports";
1143 # user didn't choose either epoll or select for their OS.
1144 # default them to USE_SELECT (ewwy puke puke)
1146 print FILEHANDLE "#define USE_SELECT\n";
1147 $se = "socketengine_select";
1149 print FILEHANDLE "\n#endif\n";
1155 open(FILEHANDLE, ">include/inspircd_se_config.h");
1156 print FILEHANDLE <<EOF;
1157 /* Auto generated by configure, do not modify or commit to svn! */
1158 #ifndef __CONFIGURATION_SOCKETENGINE__
1159 #define __CONFIGURATION_SOCKETENGINE__
1169 # Create a Modules List..
1171 foreach $i (@modlist)
1173 $modules .= "m_".$i.".so ";
1175 chomp($modules); # Remove Redundant whitespace..
1177 opendir(DIRHANDLE, "src/modules");
1178 foreach $name (sort readdir(DIRHANDLE)) {
1179 if ($name =~ /^m_(.+?)$/) {
1180 if (opendir(MDIRHANDLE, "src/modules/$name") != 0) {
1181 closedir(MDIRHANDLE);
1182 $modules .= "$name.so ";
1186 closedir(DIRHANDLE);
1189 # Write all .in files.
1192 my $exe = "inspircd";
1194 opendir(DIRHANDLE, $this);
1196 # Do this once here, and cache it in the .*.inc files,
1197 # rather than attempting to read src/version.sh from
1198 # compiled code -- we might not have the source to hand.
1199 # Fix for bug#177 by Brain.
1201 chomp(my $version = `sh ./src/version.sh`);
1202 chomp(my $revision = getrevision());
1203 $version = "$version(r$revision)";
1206 if ($config{IS_DARWIN} eq "YES")
1210 # We can actually parse any file starting with . and ending with .inc,
1211 # but right now we only parse .inspircd.inc to form './inspircd'
1213 foreach $name (sort readdir(DIRHANDLE)) {
1214 if ($name =~ /^\.(.+)\.inc$/) {
1217 # Bug #353, omit this on non-darwin
1218 next if (($config{OSNAME} !~ /darwin/) && ($file eq "org.inspircd.plist"));
1220 # All .name.inc files need parsing!
1222 open(FILEHANDLE, ".$file.inc");
1223 while (<FILEHANDLE>) {
1228 $tmp =~ s/\@CC\@/$config{CC}/;
1229 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
1230 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
1231 $tmp =~ s/\@DEVELOPER\@/$config{DEVELOPER}/;
1232 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
1233 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/;
1234 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
1235 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
1236 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
1237 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
1238 $tmp =~ s/\@LIBRARY_EXT\@/$LIBEXT/;
1239 $tmp =~ s/\@MODULES\@/$modules/;
1240 $tmp =~ s/\@STARTSCRIPT\@/$config{STARTSCRIPT}/;
1241 $tmp =~ s/\@DESTINATION\@/$config{DESTINATION}/;
1242 $tmp =~ s/\@EXTRA_DIR\@/$config{EXTRA_DIR}/;
1243 $tmp =~ s/\@EXECUTABLE\@/$exe/;
1244 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
1245 $tmp =~ s/\@VERSION\@/$version/;
1247 print "Writing \033[1;32m$file\033[0m\n";
1248 open(FILEHANDLE, ">$file");
1249 print FILEHANDLE $tmp;
1252 closedir(DIRHANDLE);
1254 # Make inspircd executable!
1255 chmod 0744, 'inspircd';
1257 print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
1258 write_dynamic_makefile();
1259 write_dynamic_modules_makefile();
1262 sub write_dynamic_modules_makefile {
1263 # Modules Makefile..
1264 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1265 open(FILEHANDLE, ">src/modules/Makefile");
1268 # Module Makefile Header
1270 print FILEHANDLE <<EOF;
1271 ###################################################
1272 # Copyright 2002-2007 The InspIRCd Development Team
1273 # http://www.inspircd.org/wiki/index.php/Credits
1275 # Thanks to Andrew Church <achurch\@achurch.org>
1276 # for assisting with making this work right.
1278 # Automatically Generated by ./configure to add a
1279 # modules please run ./configure -modupdate
1280 ###################################################
1286 if ($config{OSNAME} =~ /darwin/) {
1287 print FILEHANDLE <<EOCHEESE;
1289 PICLDFLAGS = -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) -bundle
1293 print FILEHANDLE <<EOCHEESE;
1295 PICLDFLAGS = -fPIC -DPIC -shared \$(FLAGS)
1301 # End Module Makefile Header
1304 # Create a Modules List..
1310 foreach $i (@modlist) {
1312 # Write Entry to the MakeFile
1314 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1315 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1316 $deps = getdependencies("src/modules/m_".$i.".cpp");
1318 #print "file: $i: cmflags=$cmflags; liflags=$liflags; deps=$deps\n";
1320 print FILEHANDLE <<EOCHEESE;
1321 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
1322 \$(CC) -pipe -I../../include \$(FLAGS) $cmflags \$(PICLDFLAGS) $liflags -export-dynamic -o m_$i.so m_$i.cpp
1324 $crud = $crud . " install -m \$(INSTMODE) m_$i.so \$(MODPATH)\n";
1326 # End Write Entry to the MakeFile
1330 opendir(DIRHANDLE, "src/modules");
1331 foreach $name (sort readdir(DIRHANDLE)) {
1332 if ($name =~ /^m_(.+?)$/) {
1337 # A module made of multiple files, in a dir, e.g. src/modules/m_spanningtree/
1338 if (opendir(MDIRHANDLE, "src/modules/$name") != 0) {
1339 read_module_directory("src/modules/$name", $name);
1340 print "Composing Makefile rules for directory \033[1;32m$name\033[0m... (\033[1;32m$mfcount files found\033[0m)\n";
1341 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";
1342 if ($config{IS_DARWIN} eq "YES") {
1343 print FILEHANDLE " \$(CC) -pipe -twolevel_namespace -undefined dynamic_lookup \$(FLAGS) $mliflags -bundle -o $name.so $mobjs\n";
1345 print FILEHANDLE " \$(CC) -pipe \$(FLAGS) -shared $mliflags -o $name.so $mobjs\n";
1347 print FILEHANDLE "\n$mfrules\n";
1348 closedir(MDIRHANDLE);
1349 $crud = $crud . " install -m \$(INSTMODE) $name.so \$(MODPATH)\n";
1353 closedir(DIRHANDLE);
1355 print FILEHANDLE "modinst:\n \@echo \"Installing modules...\"\n" . $crud;
1358 sub read_module_directory {
1359 my ($dpath, $reldpath) = @_;
1361 if (opendir(MDIRHANDLE, $dpath) == 0) {
1365 foreach $fname (sort readdir(MDIRHANDLE)) {
1366 if ($fname =~ /\.cpp$/) {
1367 $cmflags = getcompilerflags("$dpath/$fname");
1368 $mliflags = $mliflags . " " . getlinkerflags("$dpath/$fname");
1369 $deps = getdependencies("$dpath/$fname");
1371 $oname =~ s/\.cpp$/.o/g;
1372 $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";
1373 $mfrules = $mfrules . " \$(CC) -pipe -I../../include -I. \$(FLAGS) $cmflags -export-dynamic -o $reldpath/$oname -c $reldpath/$fname\n\n";
1374 $mobjs = $mobjs . " $reldpath/$oname";
1377 elsif ((-d "$dpath/$fname") && !($fname eq ".") && !($fname eq "..")) {
1378 read_module_directory($dpath."/".$fname, $reldpath."/".$fname);
1385 # Yes i know we could use gcc -M but it seems to ideneify a lot of 'deep'
1386 # dependencies which are not relevent in C++.
1390 open (CPP, "<$file") or die("Can't open $file for reading!");
1395 foreach my $d (@ignoredeps)
1401 foreach my $dep (@immutabledeps)
1403 $immutable = $immutable . "../include/$dep ";
1405 $immutable =~ s/ $//g;
1407 while (chomp($line = <CPP>))
1409 if ($line =~ /#include "(.+\.h)"/)
1411 if (!exists($dupe{$1}))
1413 $retlist = $retlist . "../include/$1 ";
1419 return length($immutable) ? $immutable . " " . $retlist : $retlist;
1422 sub write_dynamic_makefile {
1426 opendir(DIRHANDLE, "src/commands");
1427 foreach $name (sort readdir(DIRHANDLE)) {
1428 if ($name =~ /^cmd_(.+)\.cpp$/) {
1429 $cmdlist[$i++] = $1;
1432 closedir(DIRHANDLE);
1434 $se = "socketengine_select";
1435 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1436 $se = "socketengine_kqueue";
1438 elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1439 $se = "socketengine_epoll";
1441 elsif (($has_ports) && ($config{USE_PORTS} eq "y")) {
1442 $se = "socketengine_ports";
1445 $extrasources{"socketengine.cpp"} = $se . ".cpp";
1446 $extraobjects{"socketengine.cpp"} = $se . ".o";
1448 $freebsd4libs = $config{CRAQ};
1453 if ($config{IS_DARWIN} eq "YES")
1455 $libraryext = "dylib";
1456 $othercrap = " \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspircd.cpp\n \$(CC) -pipe -dynamic -bind_at_load -L. -o inspircd \$(LDLIBS) inspircd.o "
1461 $othercrap = " \$(CC) -pipe -I../include -Wl,--rpath -Wl,$config{LIBRARY_DIR} \$(FLAGS) $freebsd4libs -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) ";
1464 foreach my $cpp (sort keys %filelist)
1466 $all = $all . $filelist{$cpp} . "." . $libraryext . " ";
1467 $all_libsonly = $all_libsonly . $filelist{$cpp} . "." . $libraryext . " ";
1469 $all = $all . "moo inspircd\n";
1471 $othercrap = $othercrap . " $all_libsonly\n\n";
1473 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1476 CC = im a cheezeball
1477 CXXFLAGS = -I../include \${FLAGS}
1478 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1479 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1483 print FH "$all\n\n";
1485 $deps = calcdeps("src/inspircd.cpp");
1486 print FH "inspircd: inspircd.cpp $deps $all_libsonly\n";
1487 print FH "$othercrap\n";
1489 foreach my $cpp (sort keys %filelist)
1491 my $thislib = $filelist{$cpp} . "." . $libraryext;
1494 $objs =~ s/\.cpp$/.o/;
1495 if (exists($extraobjects{$cpp}))
1497 $objs = $objs . " " . $extraobjects{$cpp};
1499 if (exists($extrasources{$cpp}))
1501 $rawcpp = $rawcpp . " " . $extrasources{$cpp};
1503 if ($config{IS_DARWIN} eq "YES")
1505 $libcrap = "-install_name " . $config{LIBRARY_DIR} . "/" . $thislib . " -dynamiclib -twolevel_namespace -undefined dynamic_lookup";
1509 $libcrap = "-Wl,--rpath -Wl," . $config{LIBRARY_DIR} . " -shared";
1511 $deps = calcdeps("src/$cpp");
1512 if (exists($extrasources{$cpp}))
1514 foreach my $seperate (sort split(' ',$extrasources{$cpp}))
1516 $d = calcdeps("src/$extrasources{$cpp}") . " ";
1519 $deps = $deps . $d . " ";
1523 print FH $thislib . ": $cpp $deps ". $specialdeps{$cpp} . "\n";
1524 print FH " \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c $rawcpp\n";
1525 if (exists($extrabuildlines{$cpp}))
1527 print FH " " . $extrabuildlines{$cpp} . "\n";
1529 print FH " \$(CC) -pipe $libcrap -o " . $thislib . " " . $objs . "\n\n";
1532 print FH "moo:\n \${MAKE} -C \"commands\" DIRNAME=\"src/commands\" CC=\"\$(CC)\" \$(MAKEARGS)\n\n";
1534 # close main makefile
1537 # generate a list of .so
1538 foreach my $cmd (@cmdlist) {
1539 $cmdobjs = $cmdobjs . "cmd_$cmd.so ";
1542 # and now reopen the commands makefile
1543 open(FH,">src/commands/Makefile") or die("Could not write src/commands/Makefile");
1546 CXXFLAGS = -I../../include ${FLAGS}
1553 # now print the command file details.
1554 foreach my $cmd (@cmdlist) {
1556 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
1557 \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1558 \$(CC) -pipe $SHARED -o cmd_$cmd.so cmd_$cmd.o
1562 #try build a .so, no intermediate .o
1563 # \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic $SHARED -o cmd_$cmd.so
1565 #this works for sure
1566 # \$(CC) -pipe -I../../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1567 # \$(CC) -pipe $SHARED -o cmd_$cmd.so cmd_$cmd.o