3 # InspIRCd Configuration Script
5 # Copyright 2003 The ChatSpike Development Team
6 # <brain@chatspike.net>
7 # <Craig@chatspike.net>
9 # [14:21] Brain: <matrix impression> i know perl-fu!
13 ########################################
15 chomp($topdir = `pwd`);
16 $this = resolve_directory($topdir); # PWD, Regardless.
17 @modlist = (); # Declare for Module List..
18 %config = (); # Initiate Configuration Hash..
19 $config{ME} = resolve_directory($topdir); # Present Working Directory
20 $config{BASE_DIR} = $config{ME}; # Use CWD as 'Base' Directory.
21 $config{CONFIG_DIR} = resolve_directory($config{ME}."/conf"); # Configuration Directory
22 $config{MODULE_DIR} = resolve_directory($config{ME}."/modules"); # Modules Directory
23 $config{BINARY_DIR} = resolve_directory($config{ME}."/bin"); # Binary Directory
24 $config{LIBRARY_DIR} = resolve_directory($config{ME}."/lib"); # Library Directory
25 chomp($config{HAS_GNUTLS} = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
26 chomp($config{HAS_OPENSSL} = `openssl version 2>/dev/null`); # Openssl version
27 $config{USE_GNUTLS} = "n"; # Use gnutls.
28 $config{USE_OPENSSL} = "n"; # Use openssl.
29 $config{OPTIMITEMP} = "0"; # Default Optimisation Value
30 $config{OPTIMISATI} = "-g"; # Optimisation Flag
31 $config{NICK_LENGT} = "31"; # Default Nick Length
32 $config{CHAN_LENGT} = "64"; # Default Channel Name Length
33 $config{MAX_CHANNE} = "20"; # Default Max. Channels per user
34 $config{MAX_OPERCH} = "60"; # Default Max. Channels per oper
35 $config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once.
36 $config{HAS_STRLCPY} = "false"; # strlcpy Check.
37 $config{HAS_STDINT} = "false"; # stdint.h check
38 $config{HAS_EXECINFO} = "0"; # execinfo.h Check.
39 $config{USE_KQUEUE} = "y"; # kqueue enabled
40 $config{USE_EPOLL} = "y"; # epoll enabled
41 $config{THREADED_DNS} = "n"; # threaded dns (experimental)
42 $config{IPV6} = "n"; # IPv6 support (experimental)
43 $config{STATIC_LINK} = "no"; # are doing static modules?
44 chomp($config{MAX_CLIENT_T} = `sh -c \"ulimit -n\"`); # FD Limit
45 chomp($config{MAX_DESCRIPTORS} = `sh -c \"ulimit -n\"`); # Hard FD Limit
46 chomp($config{GCCVER} = `g++ -dumpversion | cut -c 1`); # Major GCC Version
47 chomp($config{OSNAME} = `/bin/uname`); # Operating System Name
48 $config{CC} = "g++"; # C++ compiler
49 $config{MAKEORDER} = "ircd mods"; # build order
50 $config{STATICLIBS} = ""; # library archive path
51 $config{MAX_IDENT} = "12"; # max ident size
52 $config{MAX_QUIT} = "255"; # max quit message size
53 $config{MAX_TOPIC} = "307"; # max topic size
54 $config{MAX_KICK} = "255"; # max kick message size
55 $config{MAX_GECOS} = "128"; # max GECOS size
56 $config{MAX_AWAY} = "200"; # max AWAY size
60 $config{HAS_OPENSSL} =~ /OpenSSL (\S+) \d+ \S+ \d{4}/;
61 $config{HAS_OPENSSL} = $1;
63 if ($config{GCCVER} eq "") {
64 print "g++ was not found! You require g++ (the GNU C++ compiler, part of GCC) to build InspIRCd!\n";
68 # Minihack! Convert Cygwin to 'Cyg-Static' so i can
69 # Keep my dynamic module experiments here for later
72 if ($config{OSNAME} =~ /CYGWIN/) {
73 $config{OSNAME} = "CYG-STATIC";
76 if ((!$config{OSNAME}) || ($config{OSNAME} eq "")) {
77 chomp($config{OSNAME} = `/usr/bin/uname`);
78 if ((!$config{OSNAME}) || ($config{OSNAME} eq "")){
79 $config{OSNAME} = "Unknown";
83 if (!$config{MAX_CLIENT_T}) {
84 $config{MAX_CLIENT_T} = 1024; # Set a reasonable 'Default'
85 $fd_scan_fail = "true"; # Used Later
88 # Get and Set some important vars..
91 my $arg = $ARGV[0]; # Do Some Argument Checks..
92 if ($arg eq "-clean") {
93 system("rm -rf .config.cache");
94 } # Remove the config.cache file.
96 if ($arg eq "-update") {
97 # Does the cache file exist?
99 # No, No it doesn't.. *BASH*
100 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
103 # We've Loaded the cache file and all our variables..
104 print "Updating Files..\n";
106 $has_epoll = $config{HAS_EPOLL};
107 $has_kqueue = $config{HAS_KQUEUE};
114 if ($arg eq "-modupdate") {
115 # Does the cache file exist?
117 # No, No it doesn't.. *BASH*
118 print "You have not run ./configure before. Please do this before trying to run the update script.\n";
121 # We've Loaded the cache file and all our variables..
122 print "Updating Files..\n";
124 $has_epoll = $config{HAS_EPOLL};
125 $has_kqueue = $config{HAS_KQUEUE};
134 if ($arg eq "-svnupdate") {
136 open(FH,"<.svn/entries") or $fail = 1;
138 print "This is not an SVN copy of InspIRCd.\n";
141 system("svn update");
142 system("perl configure -update");
143 if ($ARGV[1] eq "rebuild") {
144 system("make install");
149 print "Checking for cache from previous configure...\n";
151 print "Checking operating system version...\n";
154 if (!$config{MAX_CLIENT}) {
155 # If the cache hasn't set the max clients, copy the variable of MAX_CLIENT_T, this
156 # allows us to keep _T for testing purposes. (ie. "Are you sure you want to go
157 # higher than the found value" :))
158 $config{MAX_CLIENT} = $config{MAX_CLIENT_T};
161 printf "Checking if stdint.h exists... ";
162 $config{HAS_STDINT} = "true";
164 open(STDINT, "</usr/include/stdint.h") or $config{HAS_STDINT} = "false";
165 if ($config{HAS_STDINT} eq "true") {
168 print "yes\n" if $config{HAS_STDINT} eq "true";
169 print "no\n" if $config{HAS_STDINT} eq "false";
172 printf "Checking if strlcpy exists... ";
173 # Perform the strlcpy() test..
174 $config{HAS_STRLCPY} = "false";
176 open(STRLCPY, "</usr/include/string.h") or $fail = 1;
178 while (chomp($line = <STRLCPY>)) {
179 # try and find the delcaration of:
180 # size_t strlcpy(...)
181 if ($line =~ /size_t(\0x9|\s)+strlcpy/) {
182 $config{HAS_STRLCPY} = "true";
187 print "yes\n" if $config{HAS_STRLCPY} eq "true";
188 print "no\n" if $config{HAS_STRLCPY} eq "false";
190 printf "Checking if execinfo.h exists... ";
191 $config{HAS_EXECINFO} = "0";
193 open(EXECINFO, "</usr/include/execinfo.h") or $fail = 1;
196 open(EXECINFO, "</usr/local/include/execinfo.h") or $fail = 1;
198 printf "/usr/local/include/execinfo.h\n";
199 $config{HAS_EXECINFO} = "1";
203 printf "Not found!\n";
207 printf "/usr/include/execinfo.h\n";
208 $config{HAS_EXECINFO} = "1";
212 printf "Checking if kqueue exists... ";
215 open(KQUEUE, "</usr/include/sys/event.h") or $fail = 1;
217 while (chomp($line = <KQUEUE>)) {
218 # try and find the delcaration of:
220 if ($line =~ /int(\0x9|\s)+kqueue/) {
226 print "yes\n" if $has_kqueue == 1;
227 print "no\n" if $has_kqueue == 0;
229 printf "Checking if epoll exists... ";
232 open(EPOLL, "</usr/include/sys/epoll.h") or $fail = 1;
238 my $kernel = `uname -r`;
240 if (($kernel =~ /2\.0/) || ($kernel =~ /2\.2/) || ($kernel =~ /2\.4/)) {
244 print "yes\n" if $has_epoll == 1;
245 print "no\n" if $has_epoll == 0;
247 if (($config{OSNAME} =~ /CYGWIN/) || ($config{OSNAME} eq "CYG-STATIC")) {
248 $config{HAS_STRLCPY} = "true";
251 $config{HAS_EPOLL} = $has_epoll;
252 $config{HAS_KQUEUE} = $has_kqueue;
254 printf "Checking for libgnutls... ";
255 if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) {
257 $config{HAS_GNUTLS} = "y";
260 $config{HAS_GNUTLS} = "n";
263 printf "Checking for openssl... ";
264 if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) {
266 $config{HAS_OPENSSL} = "y";
269 $config{HAS_OPENSSL} = "n";
272 ################################################################################
273 # BEGIN INTERACTIVE PART #
274 ################################################################################
278 # Display Splash Logo..
280 chomp($wholeos = `uname -mnr`);
282 my $rev = getrevision();
283 # Display Introduction Message..
285 Welcome to the InspIRCd Configuration program!
287 *** If you are unsure of any of these values, leave it blank for ***
288 *** standard settings that will work, and your server will run ***
289 *** using them. If you are running this server as part of a ***
290 *** larger network, you must consult with your network admins ***
291 *** for the proper values to use, or server links will be unstable! ***
293 Press \033[1m<RETURN>\033[0m to accept the default for any option, or enter
294 a new value. Please note: You will \033[1mHAVE\033[0m to read the docs
295 dir, otherwise you won't have a config file!
297 Your operating system is: \033[1;32m$config{OSNAME}\033[0m ($wholeos), fdmax: $config{MAX_CLIENT_T}
298 Your InspIRCd revision ID is \033[1;32mr$rev\033[0m";
300 print " (Non-SVN build)";
304 $config{CHANGE_COMPILER} = "n";
305 print "I have detected the following compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
307 while (($config{GCCVER} < 3) || ($config{GCCVER} eq "")) {
308 print "\033[1;32mIMPORTANT!\033[0m A GCC 2.x compiler has been detected, and
309 should NOT be used. You should probably specify a newer compiler.\n\n";
310 yesno(CHANGE_COMPILER,"Do you want to change the compiler?");
311 if ($config{CHANGE_COMPILER} =~ /y/i) {
312 print "What command do you want to use to invoke your compiler?\n";
313 print "[\033[1;32m$config{CC}\033[0m] -> ";
314 chomp($config{CC} = <STDIN>);
315 if ($config{CC} eq "") {
318 chomp($foo = `$config{CC} -dumpversion | cut -c 1`);
320 chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers
321 print "Queried compiler: \033[1;32m$config{CC}\033[0m (version \033[1;32m$config{GCCVER}.x\033[0m)\n";
322 if ($config{GCCVER} < 3) {
323 print "\033[1;32mGCC 2.x WILL NOT WORK!\033[0m. Let's try that again, shall we?\n";
327 print "\033[1;32mWARNING!\033[0m Could not execute the compiler you specified. You may want to try again.\n";
334 # Directory Settings..
335 my $tmpbase = $config{BASE_DIR};
336 dir_check("do you wish to install the InspIRCd base", "BASE_DIR");
337 if ($tmpbase ne $config{BASE_DIR}) {
338 $config{CONFIG_DIR} = resolve_directory($config{BASE_DIR}."/conf"); # Configuration Directory
339 $config{MODULE_DIR} = resolve_directory($config{BASE_DIR}."/modules"); # Modules Directory
340 $config{BINARY_DIR} = resolve_directory($config{BASE_DIR}."/bin"); # Binary Directory
341 $config{LIBRARY_DIR} = resolve_directory($config{BASE_DIR}."/lib"); # Library Directory
344 dir_check("are the configuration files", "CONFIG_DIR");
345 dir_check("are the modules to be compiled to", "MODULE_DIR");
346 dir_check("is the IRCd binary to be placed", "BINARY_DIR");
347 dir_check("are the IRCd libraries to be placed", "LIBRARY_DIR");
350 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?");
354 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?");
357 $chose_hiperf = (($config{USE_EPOLL} eq "y") || ($config{USE_KQUEUE} eq "y"));
358 if (!$chose_hiperf) {
359 print "No high-performance socket engines are available, or you chose\n";
360 print "not to enable one. Defaulting to select() engine.\n\n";
363 yesno(IPV6,"Would you like to enable experimental IPv6 support?");
366 if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
367 print "I have detected both GnuTLS and OpenSSL on your system.\n";
368 print "I will default to GnuTLS. If you wish to use OpenSSL\n";
369 print "instead, you should enable the OpenSSL module yourself\n";
370 print "by copying it from src/modules/extra to src/modules.\n\n";
373 if ($config{HAS_GNUTLS} eq "y") {
374 yesno(USE_GNUTLS, "Would you like to enable SSL Support?");
375 if ($config{USE_GNUTLS} eq "y") {
376 print "\nUsing GnuTLS SSL module.\n";
378 } elsif ($config{HAS_OPENSSL} eq "y") {
379 yesno(USE_OPENSSL, "Would you like to enable SSL Support?");
380 if ($config{USE_OPENSSL} eq "y") {
381 print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
385 print "\nThe following questions will ask you for various figures relating\n";
386 print "To your IRCd install. Please note that these should usually be left\n";
387 print "as defaults unless you have a real reason to change them. If they\n";
388 print "changed, then the values must be identical on all servers on your\n";
389 print "network, or malfunctions and/or crashes may occur, with the exception\n";
390 print "of the 'maximum number of clients' setting which may be different on\n";
391 print "different servers on the network.\n\n";
393 # File Descriptor Settings..
396 print "Maximum number of clients at any one time ($config{MAX_CLIENT_T})\n";
397 print "[\033[1;32m$config{MAX_CLIENT}\033[0m] -> ";
398 chomp($var = <STDIN>);
400 $var = $config{MAX_CLIENT};
402 if ($var =~ /^\d+$/) {
403 if (($var > $config{MAX_CLIENT_T}) && ($fd_scan_failed ne true)) {
404 # Client has entered a larger number than the 'discovered' value
406 print "WARNING: Our scans have indicated that you are attempting
407 to use more sockets than there are avaliable. Are you sure
408 you wish to do this? It may cause the IRCd to malfunction [y/n]
409 [\033[1;32mn\033[0m] -> $c";
410 chomp($tmp = <STDIN>);
412 print "Please enter the correct value.\n\n";
417 print "You must enter a number in this field. Please try again.\n\n";
420 # If we get here, we should be good to go.
421 $config{MAX_CLIENT} = $var;
428 print "What is the maximum length of nicknames?\n";
429 print "[\033[1;32m$config{NICK_LENGT}\033[0m] -> ";
430 chomp($var = <STDIN>);
432 $var = $config{NICK_LENGT};
434 if ($var =~ /^\d+$/) {
435 # We don't care what the number is, set it and be on our way.
436 $config{NICK_LENGT} = $var;
440 print "You must enter a number in this field. Please try again.\n\n";
446 print "What is the maximum length of channel names?\n";
447 print "[\033[1;32m$config{CHAN_LENGT}\033[0m] -> ";
448 chomp($var = <STDIN>);
450 $var = $config{CHAN_LENGT};
452 if ($var =~ /^\d+$/) {
453 # We don't care what the number is, set it and be on our way.
454 $config{CHAN_LENGT} = $var;
458 print "You must enter a number in this field. Please try again.\n\n";
464 print "What is the maximum number of channels a normal user may join at any one time?\n";
465 print "[\033[1;32m$config{MAX_CHANNE}\033[0m] -> ";
466 chomp($var = <STDIN>);
468 $var = $config{MAX_CHANNE};
470 if ($var =~ /^\d+$/) {
471 # We don't care what the number is, set it and be on our way.
472 $config{MAX_CHANNE} = $var;
476 print "You must enter a number in this field. Please try again.\n\n";
482 print "What is the maximum number of channels an oper may join at any one time?\n";
483 print "[\033[1;32m$config{MAX_OPERCH}\033[0m] -> ";
484 chomp($var = <STDIN>);
486 $var = $config{MAX_OPERCH};
488 if ($var =~ /^\d+$/) {
489 # We don't care what the number is, set it and be on our way.
490 $config{MAX_OPERCH} = $var;
498 print "What is the maximum number of mode changes in one line?\n";
499 print "[\033[1;32m$config{MAXI_MODES}\033[0m] -> ";
500 chomp($var = <STDIN>);
502 $var = $config{MAXI_MODES};
504 if ($var =~ /^\d+$/) {
505 # We don't care what the number is, set it and be on our way.
506 $config{MAXI_MODES} = $var;
510 print "You must enter a number in this field. Please try again.\n\n";
516 print "What is the maximum length of an ident (username)?\n";
517 print "[\033[1;32m$config{MAX_IDENT}\033[0m] -> ";
518 chomp($var = <STDIN>);
520 $var = $config{MAX_IDENT};
522 if ($var =~ /^\d+$/) {
523 # We don't care what the number is, set it and be on our way.
524 $config{MAX_IDENT} = $var;
528 print "You must enter a number in this field. Please try again.\n\n";
534 print "What is the maximum length of a quit message?\n";
535 print "[\033[1;32m$config{MAX_QUIT}\033[0m] -> ";
536 chomp($var = <STDIN>);
538 $var = $config{MAX_QUIT};
540 if ($var =~ /^\d+$/) {
541 # We don't care what the number is, set it and be on our way.
542 $config{MAX_QUIT} = $var;
546 print "You must enter a number in this field. Please try again.\n\n";
552 print "What is the maximum length of a channel topic?\n";
553 print "[\033[1;32m$config{MAX_TOPIC}\033[0m] -> ";
554 chomp($var = <STDIN>);
556 $var = $config{MAX_TOPIC};
558 if ($var =~ /^\d+$/) {
559 # We don't care what the number is, set it and be on our way.
560 $config{MAX_TOPIC} = $var;
564 print "You must enter a number in this field. Please try again.\n\n";
570 print "What is the maximum length of a kick message?\n";
571 print "[\033[1;32m$config{MAX_KICK}\033[0m] -> ";
572 chomp($var = <STDIN>);
574 $var = $config{MAX_KICK};
576 if ($var =~ /^\d+$/) {
577 # We don't care what the number is, set it and be on our way.
578 $config{MAX_KICK} = $var;
582 print "You must enter a number in this field. Please try again.\n\n";
588 print "What is the maximum length of a GECOS (real name) field?\n";
589 print "[\033[1;32m$config{MAX_GECOS}\033[0m] -> ";
590 chomp($var = <STDIN>);
592 $var = $config{MAX_GECOS};
594 if ($var =~ /^\d+$/) {
595 # We don't care what the number is, set it and be on our way.
596 $config{MAX_GECOS} = $var;
600 print "You must enter a number in this field. Please try again.\n\n";
606 print "What is the maximum length of an away message?\n";
607 print "[\033[1;32m$config{MAX_AWAY}\033[0m] -> ";
608 chomp($var = <STDIN>);
610 $var = $config{MAX_AWAY};
612 if ($var =~ /^\d+$/) {
613 # We don't care what the number is, set it and be on our way.
614 $config{MAX_AWAY} = $var;
618 print "You must enter a number in this field. Please try again.\n\n";
623 print "Enter the Level Of Binary optimisation. This is a number between 0 and 3.
624 The InspIRCd Team will NOT support any bug reports above 0. Also note,
625 the IRCd behaviour will be different depending on this value. Please
626 read the documentation for more information.
628 The higher the number, the more optimised your binary will be. This
629 value will default to 0 if you either don't enter a number, or enter
630 a value outside the range.
632 As always, if you are unsure, just press enter and accept the default.\n\n";
633 print "[\033[1;32m$config{OPTIMITEMP}\033[0m] -> ";
634 chomp($var = <STDIN>);
636 $var = $config{OPTIMITEMP};
640 $config{OPTIMITEMP} = 1;
641 $config{OPTIMISATI} = "-O";
642 } elsif ($var eq "2") {
643 $config{OPTIMITEMP} = 2;
644 $config{OPTIMISATI} = "-O2";
645 } elsif ($var eq "3") {
646 $config{OPTIMITEMP} = 3;
647 $config{OPTIMISATI} = "-O3";
649 $config{OPTIMITEMP} = 0;
650 $config{OPTIMISATI} = "-g";
653 print "\n\033[1;32mPre-build configuration is complete!\033[0m\n\n";
654 print "\033[0mBase install path:\033[1;32m\t\t$config{BASE_DIR}\033[0m\n";
655 print "\033[0mConfig path:\033[1;32m\t\t\t$config{CONFIG_DIR}\033[0m\n";
656 print "\033[0mModule path:\033[1;32m\t\t\t$config{MODULE_DIR}\033[0m\n";
657 print "\033[0mLibrary path:\033[1;32m\t\t\t$config{LIBRARY_DIR}\033[0m\n";
658 print "\033[0mMax connections:\033[1;32m\t\t$config{MAX_CLIENT}\033[0m\n";
659 print "\033[0mMax User Channels:\033[1;32m\t\t$config{MAX_CHANNE}\033[0m\n";
660 print "\033[0mMax Oper Channels:\033[1;32m\t\t$config{MAX_OPERCH}\033[0m\n";
661 print "\033[0mMax nickname length:\033[1;32m\t\t$config{NICK_LENGT}\033[0m\n";
662 print "\033[0mMax channel length:\033[1;32m\t\t$config{CHAN_LENGT}\033[0m\n";
663 print "\033[0mMax mode length:\033[1;32m\t\t$config{MAXI_MODES}\033[0m\n";
664 print "\033[0mMax ident length:\033[1;32m\t\t$config{MAX_IDENT}\033[0m\n";
665 print "\033[0mMax quit length:\033[1;32m\t\t$config{MAX_QUIT}\033[0m\n";
666 print "\033[0mMax topic length:\033[1;32m\t\t$config{MAX_TOPIC}\033[0m\n";
667 print "\033[0mMax kick length:\033[1;32m\t\t$config{MAX_KICK}\033[0m\n";
668 print "\033[0mMax name length:\033[1;32m\t\t$config{MAX_GECOS}\033[0m\n";
669 print "\033[0mMax away length:\033[1;32m\t\t$config{MAX_AWAY}\033[0m\n";
670 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.x\033[0m\n";
671 print "\033[0mOptimization Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
672 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n";
673 print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n";
674 print "\033[0mMultithread DNS:\033[1;32m\t\t$config{THREADED_DNS}\033[0m\n";
675 print "\033[0mIPv6 Support:\033[1;32m\t\t\t$config{IPV6}\033[0m\n";
676 print "\033[0mGnuTLS Support:\033[1;32m\t\t\t$config{USE_GNUTLS}\033[0m\n";
677 print "\033[0mOpenSSL Support:\033[1;32m\t\t$config{USE_OPENSSL}\033[0m\n\n";
679 if ($config{USE_GNUTLS} eq "y") {
681 open(TMP, "<src/modules/m_ssl_gnutls.cpp") or $failed = 1;
684 print "Symlinking src/modules/m_ssl_gnutls.cpp from extra/\n";
685 chdir("src/modules");
686 system("ln -s extra/m_ssl_gnutls.cpp");
691 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
693 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
696 print "SSL Certificates Not found, Generating.. \n\n
697 *************************************************************
698 * Generating the Private Key may take some time, go grab a *
699 * Coffee. Even better, to generate some more entropy if it *
700 * is taking a while, open another console and type du / a *
701 * few times and get that HD going :) Then answer the *
702 * Questions which follow. If you are unsure, just hit enter *
703 *************************************************************\n\n";
704 system("certtool --generate-privkey --outfile key.pem");
705 system("certtool --generate-self-signed --load-privkey key.pem --outfile cert.pem");
706 print "\nCertificate generation complete, copying to config directory... ";
707 system("mv key.pem $config{CONFIG_DIR}/key.pem");
708 system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
711 print "SSL Certificates found, skipping.\n\n"
713 } elsif ($config{USE_OPENSSL} eq "y") {
715 open(TMP, "<src/modules/m_ssl_openssl.cpp") or $failed = 1;
718 print "Symlinking src/modules/m_ssl_openssl.cpp from extra/\n";
719 chdir("src/modules");
720 system("ln -s extra/m_ssl_openssl.cpp");
725 open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
727 open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
730 print "SSL Certificates Not found, Generating.. \n\n
731 *************************************************************
732 * Generating the certificates may take some time, go grab a *
733 * coffee, or something. *
734 *************************************************************\n\n";
735 system("openssl req -x509 -nodes -newkey rsa:1024 -keyout key.pem -out cert.pem");
736 system("openssl dhparam -out dhparams.pem 1024");
737 print "\nCertificate generation complete, copying to config directory... ";
738 system("mv key.pem $config{CONFIG_DIR}/key.pem");
739 system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
740 system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
743 print "SSL Certificates found, skipping.\n\n"
746 if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
747 print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
755 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
756 if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
757 print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
758 print "load the required modules in your config. This configure process\n";
759 print "has just prepared these modules to be compiled for you, and has not\n";
760 print "configured them to be compiled into the core of the ircd.\n";
762 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
763 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
764 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";
767 if ($config{GCCVER} < "3") {
769 \033[1;32mWARNING!\033[0m You are attempting to compile InspIRCd on GCC 2.x!
770 GCC 2.x series compilers only had partial (read as broken) C++ support, and
771 your compile will most likely fail horribly! If you have any problems, do NOT
772 report them to the bugtracker or forums without first upgrading your compiler
773 to a newer 3.x or 4.x (or whatever is available currently) version.
777 ################################################################################
779 ################################################################################
781 # Retrieves the .config.cache file, and loads values into the main config hash.
782 open(CACHE, ".config.cache") or return undef;
785 # Ignore Blank lines, and comments..
788 my ($key, $value) = split("=", $_);
789 $value =~ /^\"(.*)\"$/;
790 # Do something with data here!
798 # Dump the contents of %config
799 print "Writing \033[1;32mcache file\033[0m for future ./configures ...\n";
800 open(FILEHANDLE, ">.config.cache");
801 foreach $key (keys %config) {
802 print FILEHANDLE "$key=\"$config{$key}\"\n";
808 my ($desc, $hash_key) = @_;
811 print "In what directory $desc?\n";
812 print "[\033[1;32m$config{$hash_key}\033[0m] -> ";
813 chomp($var = <STDIN>);
815 $var = $config{$hash_key};
817 if ($var =~ /^\~\/(.+)$/) {
818 # Convert it to a full path..
819 $var = resolve_directory($ENV{HOME} . "/" . $1);
821 if (substr($var,0,1) ne "/")
823 # Assume relative Path was given.. fill in the rest.
824 $var = $this . "/$var";
826 $var = resolve_directory($var);
828 print "$var does not exist. Create it?\n[\033[1;32my\033[0m] ";
829 chomp($tmp = <STDIN>);
830 if (($tmp eq "") || ($tmp =~ /^y/i)) {
831 # Attempt to Create the Dir..
832 $chk = system("mkdir -p \"$var\" >> /dev/null 2>&1") / 256;
834 print "Unable to create directory. ($var)\n\n";
839 # They said they don't want to create, and we can't install there.
845 # Target exists, but is not a directory.
846 print "File $var exists, but is not a directory.\n\n";
850 # Either Dir Exists, or was created fine.
851 $config{$hash_key} = $var;
858 if ($config{OSNAME} =~ /BSD$/) {
859 $config{LDLIBS} = "-Ldl -lstdc++";
860 $config{FLAGS} = "-fPIC -frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
861 $config{MAKEPROG} = "gmake";
862 if ($config{OSNAME} eq "OpenBSD") {
863 chomp($foo = `eg++ -dumpversion | cut -c 1`);
864 # theyre running the package version of gcc (eg++)... detect it and set up its version numbers.
865 # if theyre not running this, configure lets the build continue but they probably wont manage to
866 # compile as this standard version is 2.95.3!
868 $config{CC} = "eg++";
869 chomp($config{GCCVER} = `eg++ -dumpversion | cut -c 1`); # we must redo these if we change the compiler path
873 $config{LDLIBS} = "-ldl -lstdc++";
874 $config{FLAGS} = "-fPIC -frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
875 $config{MAKEPROG} = "make";
876 if ($config{OSNAME} =~ /CYGWIN/) {
877 $config{FLAGS} = "-frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
878 $config{LDLIBS} = "";
879 $config{MAKEPROG} = "/usr/bin/make";
880 $config{MAKEORDER} = "ircd mods";
881 } elsif ($config{OSNAME} eq "CYG-STATIC") {
882 $config{FLAGS} = "-frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
883 $config{LDLIBS} = "";
884 $config{MAKEPROG} = "/usr/bin/make";
885 $config{MAKEORDER} = "mods ircd";
886 $config{STATICLIBS} = "modules/mods.a";
887 $config{STATIC_LINK} = "yes";
890 if ($config{OSNAME} =~ /SunOS/) {
891 # solaris/sunos needs these
892 # socket = bsd sockets api
894 # rt = POSIX realtime extensions
895 # resolv = inet_aton only (why isnt this in nsl?!)
896 $config{LDLIBS} = $config{LDLIBS} . " -lsocket -lnsl -lrt -lresolv";
914 print "Detecting modules ";
915 opendir(DIRHANDLE, "src/modules");
916 foreach $name (sort readdir(DIRHANDLE)) {
917 if ($name =~ /^m_(.+)\.cpp$/)
920 if ($mod !~ /_static$/) {
921 $modlist[$i++] = $mod;
927 print "\nOk, $i modules.\n";
934 my $data = `svn info`;
940 $data =~ /Revision: (\d+)/;
942 if (!defined($rev)) {
949 my($writeheader) = @_;
950 # First File.. inspircd_config.h
951 chomp(my $incos = `uname -n -s -r`);
952 chomp(my $version = `sh ./src/version.sh`);
953 chomp(my $revision = getrevision());
954 $version = "$version(r$revision)";
955 chomp(my $revision2 = getrevision());
956 if ($writeheader == 1)
958 print "Writing \033[1;32minspircd_config.h\033[0m\n";
959 open(FILEHANDLE, ">include/inspircd_config.h");
960 my $NL = $config{NICK_LENGT}+1;
961 my $CL = $config{CHAN_LENGT}+1;
962 print FILEHANDLE <<EOF;
963 /* Auto generated by configure, do not modify! */
964 #ifndef __CONFIGURATION_AUTO__
965 #define __CONFIGURATION_AUTO__
967 #define CONFIG_FILE "$config{CONFIG_DIR}/inspircd.conf"
968 #define MOD_PATH "$config{MODULE_DIR}"
969 #define VERSION "$version"
970 #define REVISION "$revision2"
971 #define MAXCLIENTS $config{MAX_CLIENT}
972 #define MAX_DESCRIPTORS $config{MAX_DESCRIPTORS}
975 #define MAXCHANS $config{MAX_CHANNE}
976 #define OPERMAXCHANS $config{MAX_OPERCH}
977 #define MAXMODES $config{MAXI_MODES}
978 #define IDENTMAX $config{MAX_IDENT}
979 #define MAXQUIT $config{MAX_QUIT}
980 #define MAXTOPIC $config{MAX_TOPIC}
981 #define MAXKICK $config{MAX_KICK}
982 #define MAXGECOS $config{MAX_GECOS}
983 #define MAXAWAY $config{MAX_AWAY}
984 #define OPTIMISATION $config{OPTIMITEMP}
985 #define SYSTEM "$incos"
988 if ($config{OSNAME} =~ /SunOS/) {
989 print FILEHANDLE "#define IS_SOLARIS\n";
991 if ($config{OSNAME} =~ /CYGWIN/) {
992 print FILEHANDLE "#define IS_CYGWIN\n";
993 print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE 1024\n#endif\n";
995 if ($config{OSNAME} eq "CYG-STATIC") {
996 print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE 1024\n#endif\n";
998 if ($config{HAS_EXECINFO} eq "1") {
999 print FILEHANDLE "#define HAS_EXECINFO\n";
1001 if ($config{STATIC_LINK} eq "yes") {
1002 print FILEHANDLE "#define STATIC_LINK\n";
1004 if ($config{GCCVER} >= 3) {
1005 print FILEHANDLE "#define GCC3\n";
1007 if ($config{HAS_STRLCPY} eq "true") {
1008 print FILEHANDLE "#define HAS_STRLCPY\n";
1010 if ($config{HAS_STDINT} eq "true") {
1011 print FILEHANDLE "#define HAS_STDINT\n";
1013 if ($config{THREADED_DNS} =~ /y/i) {
1014 print FILEHANDLE "#define THREADED_DNS\n";
1016 if ($config{IPV6} =~/y/i) {
1017 print FILEHANDLE "#define IPV6\n";
1020 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1021 print FILEHANDLE "#define USE_KQUEUE\n";
1022 $se = "socketengine_kqueue";
1025 if (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1026 print FILEHANDLE "#define USE_EPOLL\n";
1027 $se = "socketengine_epoll";
1030 # user didn't choose either epoll or select for their OS.
1031 # default them to USE_SELECT (ewwy puke puke)
1033 print FILEHANDLE "#define USE_SELECT\n";
1034 $se = "socketengine_select";
1036 print FILEHANDLE "\n#endif\n";
1042 open(FILEHANDLE, ">include/inspircd_se_config.h");
1043 print FILEHANDLE <<EOF;
1044 /* Auto generated by configure, do not modify or commit to svn! */
1045 #ifndef __CONFIGURATION_SOCKETENGINE__
1046 #define __CONFIGURATION_SOCKETENGINE__
1056 # Create a Modules List..
1058 foreach $i (@modlist)
1060 if ($config{STATIC_LINK} eq "yes") {
1061 $modules .= "m_".$i.".o ";
1064 $modules .= "m_".$i.".so ";
1067 chomp($modules); # Remove Redundant whitespace..
1070 # Write all .in files.
1073 my $exe = "inspircd";
1075 if ($config{OSNAME} =~ /CYGWIN/) {
1076 $exe = "inspircd.exe";
1079 opendir(DIRHANDLE, $this);
1080 if ($config{THREADED_DNS} =~ /y/i) {
1081 $config{LDLIBS} = $config{LDLIBS} . " -pthread";
1083 foreach $name (sort readdir(DIRHANDLE)) {
1084 if ($name =~ /^\.(.+)\.inc$/) {
1086 # All .name.inc files need parsing!
1088 open(FILEHANDLE, ".$file.inc");
1089 while (<FILEHANDLE>) {
1094 $tmp =~ s/\@CC\@/$config{CC}/;
1095 $tmp =~ s/\@MAKEPROG\@/$config{MAKEPROG}/;
1096 $tmp =~ s/\@FLAGS\@/$config{FLAGS}/;
1097 $tmp =~ s/\@LDLIBS\@/$config{LDLIBS}/;
1098 $tmp =~ s/\@BASE_DIR\@/$config{BASE_DIR}/;
1099 $tmp =~ s/\@CONFIG_DIR\@/$config{CONFIG_DIR}/;
1100 $tmp =~ s/\@MODULE_DIR\@/$config{MODULE_DIR}/;
1101 $tmp =~ s/\@BINARY_DIR\@/$config{BINARY_DIR}/;
1102 $tmp =~ s/\@LIBRARY_DIR\@/$config{LIBRARY_DIR}/;
1103 $tmp =~ s/\@MODULES\@/$modules/;
1104 $tmp =~ s/\@EXECUTABLE\@/$exe/;
1105 $tmp =~ s/\@MAKEORDER\@/$config{MAKEORDER}/;
1106 $tmp =~ s/\@STATICLIBS\@/$config{STATICLIBS}/;
1108 print "Writing \033[1;32m$file\033[0m\n";
1109 open(FILEHANDLE, ">$file");
1110 print FILEHANDLE $tmp;
1113 closedir(DIRHANDLE);
1115 # Make inspircd executable!
1116 chmod 0744, 'inspircd';
1118 if ($config{STATIC_LINK} eq "yes") {
1119 print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
1120 write_static_makefile();
1121 write_static_modules_makefile();
1122 } elsif ($config{OSNAME} =~ /CYGWIN/) {
1123 print "Writing cygwin-build \033[1;32msrc/Makefile\033[0m\n";
1124 write_static_makefile();
1125 write_dynamic_modules_makefile();
1127 print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
1128 write_dynamic_makefile();
1129 write_dynamic_modules_makefile();
1133 sub getcompilerflags {
1137 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
1146 sub getlinkerflags {
1150 if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) {
1160 print "'\033[1;33m####\033[0m:'\033[1;33m##\033[0m::: \033[1;33m##\033[0m::'\033[1;33m######\033[0m::'\033[1;33m########\033[0m::'\033[1;33m####\033[0m:'\033[1;33m########\033[0m:::'\033[1;33m######\033[0m::'\033[1;33m########\033[0m::\n";
1161 print ". \033[1;33m##\033[0m:: \033[1;33m###\033[0m:: \033[1;33m##\033[0m:'\033[1;33m##\033[0m... \033[1;33m##\033[0m: \033[1;33m##\033[0m.... \033[1;33m##\033[0m:. \033[1;33m##\033[0m:: \033[1;33m##\033[0m.... \033[1;33m##\033[0m:'\033[1;33m##\033[0m... \033[1;33m##\033[0m: \033[1;33m##\033[0m.... \033[1;33m##\033[0m:\n";
1162 print ": \033[1;33m##\033[0m:: \033[1;33m####\033[0m: \033[1;33m##\033[0m: \033[1;33m##\033[0m:::..:: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:: \033[1;33m##\033[0m:: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m: \033[1;33m##\033[0m:::..:: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n";
1163 print ": \033[1;33m##\033[0m:: \033[1;33m##\033[0m \033[1;33m##\033[0m \033[1;33m##\033[0m:. \033[1;33m######\033[0m:: \033[1;33m########\033[0m::: \033[1;33m##\033[0m:: \033[1;33m########\033[0m:: \033[1;33m##\033[0m::::::: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n";
1164 print ": \033[1;33m##\033[0m:: \033[1;33m##\033[0m. \033[1;33m####\033[0m::..... \033[1;33m##\033[0m: \033[1;33m##\033[0m.....:::: \033[1;33m##\033[0m:: \033[1;33m##\033[0m.. \033[1;33m##\033[0m::: \033[1;33m##\033[0m::::::: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n";
1165 print ": \033[1;33m##\033[0m:: \033[1;33m##\033[0m:. \033[1;33m###\033[0m:'\033[1;33m##\033[0m::: \033[1;33m##\033[0m: \033[1;33m##\033[0m::::::::: \033[1;33m##\033[0m:: \033[1;33m##\033[0m::. \033[1;33m##\033[0m:: \033[1;33m##\033[0m::: \033[1;33m##\033[0m: \033[1;33m##\033[0m:::: \033[1;33m##\033[0m:\n";
1166 print "'\033[1;33m####\033[0m: \033[1;33m##\033[0m::. \033[1;33m##\033[0m:. \033[1;33m######\033[0m:: \033[1;33m##\033[0m::::::::'\033[1;33m####\033[0m: \033[1;33m##\033[0m:::. \033[1;33m##\033[0m:. \033[1;33m######\033[0m:: \033[1;33m########\033[0m::\n";
1167 print "\033[0m\033[0m....::..::::..:::......:::..:::::::::....::..:::::..:::......:::........:::\n\n";
1170 sub resolve_directory {
1172 return File::Spec->rel2abs($_[0]);
1176 my ($flag,$prompt) = @_;
1177 print "$prompt [\033[1;32m$config{$flag}\033[0m] -> ";
1178 chomp($tmp = <STDIN>);
1179 if ($tmp eq "") { $tmp = $config{$flag} }
1181 if (($tmp eq "") || ($tmp =~ /^y/i)) {
1182 $config{$flag} = "y";
1184 $config{$flag} = "n";
1189 sub write_static_modules_makefile {
1190 # Modules Makefile..
1191 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1192 open(FILEHANDLE, ">src/modules/Makefile");
1195 # Module Makefile Header
1197 print FILEHANDLE <<EOF;
1198 # (C) ChatSpike development team
1199 # Makefile by <Craig\@ChatSpike.net>
1200 # Many Thanks to Andrew Church <achurch\@achurch.org>
1201 # for assisting with making this work right.
1203 # Automatically Generated by ./configure to add a modules
1204 # please run ./configure --update
1210 # End Module Makefile Header
1213 # Create a Modules List..
1218 open(MODLIST,">include/modlist.h");
1221 # Include File Header
1223 print MODLIST <<HEADER;
1224 // Generated automatically by configure. DO NOT EDIT!
1226 #ifndef __SYMBOLS__H_CONFIGURED__
1227 #define __SYMBOLS__H_CONFIGURED__
1231 # End Include File Header
1234 # Place Module List into Include
1235 foreach $i (@modlist) {
1236 if ($i !~ /_static$/) {
1237 print MODLIST "extern \"C\" void * $i\_init (void);\n";
1240 print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
1245 foreach $i (@modlist)
1247 if ($i !~ /_static$/) {
1248 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1249 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1252 # Write Entry to the Makefile
1254 print FILEHANDLE <<EOCHEESE;
1255 m_$i.o: .m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h
1256 \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c .m_$i\_static.cpp
1257 mv .m_$i\_static.o ../m_$i.o
1261 # End Write Entry to the MakeFile
1263 print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
1264 open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
1265 open(MUNGED,">src/modules/.m_".$i."_static.cpp") or die("Could not create .m_".$i."_static.cpp");
1266 while (chomp($a = <MODULE>)) {
1267 $a =~ s/init_module/$i\_init/g;
1268 print MUNGED "$a\n";
1272 print MODLIST <<EOENT;
1273 {"m_$i.so",\&$i\_init},
1278 print MODLIST "{0}};\n\n#endif\n";
1282 sub write_dynamic_modules_makefile {
1283 # Modules Makefile..
1284 print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
1285 open(FILEHANDLE, ">src/modules/Makefile");
1288 if ($config{OSNAME} =~ /CYGWIN/) {
1289 $extra = "../inspircd.dll.a";
1293 # Module Makefile Header
1295 print FILEHANDLE <<EOF;
1296 # (C) ChatSpike development team
1297 # Makefile by <Craig\@ChatSpike.net>
1298 # Many Thanks to Andrew Church <achurch\@achurch.org>
1299 # for assisting with making this work right.
1301 # Automatically Generated by ./configure to add a modules
1302 # please run ./configure -update or ./configure -modupdate
1308 # End Module Makefile Header
1311 # Create a Modules List..
1317 foreach $i (@modlist) {
1319 # Write Entry to the MakeFile
1321 $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
1322 $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
1323 print FILEHANDLE <<EOCHEESE;
1324 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
1325 \$(CC) -pipe -I../../include \$(FLAGS) $cmflags -export-dynamic -c m_$i.cpp
1326 \$(CC) \$(FLAGS) -shared $liflags -o m_$i.so m_$i.o $extra
1329 $crud = $crud . " \@install -v -m 0700 m_$i.so \$(MODPATH)\n";
1331 # End Write Entry to the MakeFile
1334 print FILEHANDLE "modinst:\n \@echo \"Installing modules...\"\n" . $crud;
1338 sub write_static_makefile {
1339 open(FH,">src/Makefile") or die("Could not write src/Makefile!");
1342 opendir(DIRHANDLE, "src");
1343 foreach $name (sort readdir(DIRHANDLE)) {
1344 if ($name =~ /^cmd_(.+)\.cpp$/) {
1345 $cmdlist[$i++] = $1;
1348 closedir(DIRHANDLE);
1351 foreach my $cmd (@cmdlist) {
1352 $cmdobjs = $cmdobjs . "cmd_$cmd.o ";
1353 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1358 # (C) ChatSpike development team
1359 # Makefile by <Craig\@ChatSpike.net>
1360 # Makefile version 2 (statically linked core) by <brain\@inspircd.org>
1363 CC = im a cheezeball
1365 CXXFLAGS = -I../include \${FLAGS}
1366 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1367 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1371 $se = "socketengine_select";
1372 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1373 $se = "socketengine_kqueue";
1375 elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1376 $se = "socketengine_epoll";
1380 # This next section is for cygwin dynamic module builds.
1381 # Basically, what we do, is build the inspircd core as a library
1382 # then the main executable uses that. the library is capable of
1383 # loading / unloading the modules dynamically :)
1384 # Massive thanks to the guys on #cygwin @ irc.freenode.net for helping
1388 if ($config{OSNAME} =~ /CYGWIN/) {
1390 all: timer.o aes.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o message.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o inspircd.exe
1392 inspircd.exe: inspircd.dll.a
1395 inspircd.dll inspircd.dll.a: inspircd.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o message.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o aes.o timer.o snomasks.o
1396 \$(CC) -shared -Wl,--out-implib=inspircd.dll.a -o inspircd.dll \$^
1400 all: timer.o aes.o command_parse.o cull_list.o userprocess.o socketengine.o socket.o hashcomp.o channels.o mode.o xline.o inspstring.o dns.o base.o configreader.o inspsocket.o message.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o snomasks.o \$(MODULES) inspircd.exe
1402 inspircd.exe: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/base.h
1403 \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspsocket.o configreader.o message.o $cmdobjs commands.o dynamic.o users.o modules.o wildcard.o helperfuncs.o hashcomp.o socket.o socketengine.o userprocess.o cull_list.o command_parse.o aes.o timer.o snomasks.o modes/modeclasses.a \$(MODULES)
1409 cull_list.o: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1410 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1412 snomasks.o: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1413 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1415 command_parse.o: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1416 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1418 userprocess.o: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1419 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1421 socketengine.o: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1422 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1424 hashcomp.o: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1425 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1427 helperfuncs.o: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1428 \$(CC) -pipe -I/usr/local/include -L/usr/local/lib -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1430 channels.o: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1431 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1433 mode.o: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES)
1434 \${MAKE} -C "modes" DIRNAME="src/modes" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1435 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1437 xline.o: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1438 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1440 inspstring.o: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1441 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1443 dns.o: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1444 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1446 base.o: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1447 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1449 configreader.o: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1450 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1452 message.o: message.cpp ../include/base.h ../include/message.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1453 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c message.cpp
1455 commands.o: commands.cpp ../include/base.h ../include/commands.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h $srcobjs
1456 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp $cmdobjs
1458 dynamic.o: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1459 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1461 users.o: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1462 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1464 modules.o: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1465 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1467 wildcard.o: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1468 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1470 socket.o: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1471 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1473 inspsocket.o: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1474 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1476 aes.o: aes.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1477 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c aes.cpp
1479 timer.o: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1480 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1483 foreach my $cmd (@cmdlist) {
1485 cmd_$cmd.o: 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
1486 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp
1492 sub write_dynamic_makefile {
1496 opendir(DIRHANDLE, "src");
1497 foreach $name (sort readdir(DIRHANDLE)) {
1498 if ($name =~ /^cmd_(.+)\.cpp$/) {
1499 $cmdlist[$i++] = $1;
1502 closedir(DIRHANDLE);
1506 foreach my $cmd (@cmdlist) {
1507 $cmdobjs = $cmdobjs . "cmd_$cmd.o ";
1508 $srcobjs = $srcobjs . "cmd_$cmd.cpp ";
1511 if (($config{OSNAME} !~ /Linux/i) && ($config{HAS_EXECINFO} eq "1")) {
1512 $extra = "-L/usr/local/lib -lexecinfo";
1517 $se = "socketengine_select";
1518 if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) {
1519 $se = "socketengine_kqueue";
1521 elsif (($has_epoll) && ($config{USE_EPOLL} eq "y")) {
1522 $se = "socketengine_epoll";
1525 open(FH,">src/Makefile") or die("Could not write src/Makefile");
1529 # (C) ChatSpike development team
1530 # Makefile by <Craig\@ChatSpike.net>
1531 # Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
1534 CC = im a cheezeball
1536 CXXFLAGS = -I../include \${FLAGS}
1537 CPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* //' | grep -v svn)
1538 RELCPPFILES = \$(shell /bin/ls -l modes/ | grep '\\.cpp' | sed 's/^.* /modes\\//' | grep -v svn)
1540 all: libIRCDtimer.so libIRCDaes.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so libIRCDmessage.so $cmdobjs libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so libIRCDsnomasks.so inspircd
1542 inspircd: inspircd.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/channels.h ../include/globals.h ../include/inspircd_config.h ../include/socket.h libIRCDtimer.so libIRCDaes.so libIRCDcull_list.so libIRCDuserprocess.so libIRCDsocketengine.so libIRCDsocket.so libIRCDhash.so libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so libIRCDmessage.so $cmdobjs libIRCDsnomasks.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDcommand_parse.so
1543 \$(CC) -I../include $extra -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,$config{LIBRARY_DIR} \$(FLAGS) -rdynamic -L. inspircd.cpp -o inspircd \$(LDLIBS) libIRCDchannels.so libIRCDmode.so libIRCDxline.so libIRCDstring.so libIRCDasyncdns.so libIRCDbase.so libIRCDconfigreader.so libIRCDinspsocket.so libIRCDmessage.so libIRCDcommands.so libIRCDdynamic.so libIRCDusers.so libIRCDmodules.so libIRCDwildcard.so libIRCDhelper.so libIRCDhash.so libIRCDsocket.so libIRCDsocketengine.so libIRCDuserprocess.so libIRCDcull_list.so libIRCDcommand_parse.so libIRCDaes.so libIRCDtimer.so libIRCDsnomasks.so
1545 libIRCDsocketengine.so: $se.cpp socketengine.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/$se.h
1546 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socketengine.cpp $se.cpp
1547 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocketengine.so socketengine.o $se.o
1549 libIRCDsnomasks.so: snomasks.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h ../include/channels.h
1550 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c snomasks.cpp
1551 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsnomasks.so snomasks.o
1553 libIRCDcommand_parse.so: command_parse.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1554 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c command_parse.cpp
1555 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommand_parse.so command_parse.o
1557 libIRCDcull_list.so: cull_list.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h ../include/users.h ../include/channels.h
1558 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp
1559 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcull_list.so cull_list.o
1561 libIRCDuserprocess.so: userprocess.cpp ../include/base.h ../include/hashcomp.h ../include/globals.h ../include/inspircd_config.h
1562 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c userprocess.cpp
1563 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDuserprocess.so userprocess.o
1565 libIRCDhash.so: hashcomp.cpp ../include/base.h ../include/hashcomp.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1566 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c hashcomp.cpp
1567 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhash.so hashcomp.o
1569 libIRCDhelper.so: helperfuncs.cpp ../include/base.h ../include/helperfuncs.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1570 \$(CC) -pipe -I/usr/local/include -L/usr/local/lib -I../include \$(FLAGS) -export-dynamic -c helperfuncs.cpp
1571 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDhelper.so helperfuncs.o
1573 libIRCDchannels.so: channels.cpp ../include/base.h ../include/channels.h ../include/inspircd.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1574 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c channels.cpp
1575 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDchannels.so channels.o
1577 libIRCDmode.so: mode.cpp ../include/base.h ../include/mode.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h \$(RELCPPFILES)
1578 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c mode.cpp
1579 \${MAKE} -C "modes" DIRNAME="src/modes" \$(MAKEARGS) CPPFILES="\$(CPPFILES)"
1580 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmode.so mode.o modes/modeclasses.a
1582 libIRCDxline.so: xline.cpp ../include/base.h ../include/xline.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1583 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c xline.cpp
1584 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDxline.so xline.o
1586 libIRCDstring.so: inspstring.cpp ../include/base.h ../include/inspstring.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1587 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspstring.cpp
1588 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDstring.so inspstring.o
1590 libIRCDasyncdns.so: dns.cpp ../include/base.h ../include/dns.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1591 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dns.cpp
1592 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDasyncdns.so dns.o
1594 libIRCDbase.so: base.cpp ../include/base.h ../include/globals.h ../include/inspircd_config.h
1595 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c base.cpp
1596 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDbase.so base.o
1598 libIRCDconfigreader.so: configreader.cpp ../include/base.h ../include/configreader.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1599 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c configreader.cpp
1600 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDconfigreader.so configreader.o
1602 libIRCDmessage.so: message.cpp ../include/base.h ../include/message.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1603 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c message.cpp
1604 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmessage.so message.o
1606 libIRCDcommands.so: commands.cpp ../include/base.h ../include/commands.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h $srcobjs
1607 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c commands.cpp
1608 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDcommands.so commands.o $cmdobjs
1610 libIRCDdynamic.so: dynamic.cpp ../include/base.h ../include/dynamic.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1611 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c dynamic.cpp
1612 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDdynamic.so dynamic.o
1614 libIRCDusers.so: users.cpp ../include/base.h ../include/users.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1615 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c users.cpp
1616 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDusers.so users.o
1618 libIRCDmodules.so: modules.cpp ../include/base.h ../include/modules.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1619 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c modules.cpp
1620 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDmodules.so modules.o
1622 libIRCDwildcard.so: wildcard.cpp ../include/base.h ../include/wildcard.h ../include/inspircd.h ../include/channels.h ../include/users.h ../include/globals.h ../include/inspircd_config.h
1623 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c wildcard.cpp
1624 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDwildcard.so wildcard.o
1626 libIRCDsocket.so: socket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1627 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c socket.cpp
1628 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDsocket.so socket.o
1630 libIRCDinspsocket.so: inspsocket.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1631 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c inspsocket.cpp
1632 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDinspsocket.so inspsocket.o
1634 libIRCDaes.so: aes.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1635 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c aes.cpp
1636 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDaes.so aes.o
1638 libIRCDtimer.so: timer.cpp ../include/base.h ../include/inspircd.h ../include/globals.h ../include/inspircd_config.h
1639 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c timer.cpp
1640 \$(CC) -Wl,--rpath -Wl,$config{LIBRARY_DIR} -shared -o libIRCDtimer.so timer.o
1643 foreach my $cmd (@cmdlist) {
1645 cmd_$cmd.o: 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
1646 \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cmd_$cmd.cpp