]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - configure
Added max and current local/global usercounts to /lusers same way as most other ircds
[user/henk/code/inspircd.git] / configure
index 289f695213736cff3fdfa8fb20015c4bbee6e29b..e1e8156b8495077f7edaf1609f118c9b1ab5e3ed 100755 (executable)
--- a/configure
+++ b/configure
@@ -21,6 +21,10 @@ $config{CONFIG_DIR}         = resolve_directory($config{ME}."/conf");                # Configu
 $config{MODULE_DIR}         = resolve_directory($config{ME}."/modules");       # Modules Directory
 $config{BINARY_DIR}         = resolve_directory($config{ME}."/bin");           # Binary Directory
 $config{LIBRARY_DIR}        = resolve_directory($config{ME}."/lib");           # Library Directory
+chomp($config{HAS_GNUTLS}   = `libgnutls-config --version 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version.
+chomp($config{HAS_OPENSSL}  = `openssl version 2>/dev/null`);                  # Openssl version
+$config{USE_GNUTLS}         = "n";                                             # Use gnutls.
+$config{USE_OPENSSL}        = "n";                                             # Use openssl.
 $config{OPTIMITEMP}         = "0";                                             # Default Optimisation Value
 $config{OPTIMISATI}         = "-g";                                            # Optimisation Flag
 $config{NICK_LENGT}         = "31";                                            # Default Nick Length
@@ -48,6 +52,17 @@ $config{MAX_KICK}           = "255";                                         # max kick message size
 $config{MAX_GECOS}          = "128";                                           # max GECOS size
 $config{MAX_AWAY}           = "200";                                           # max AWAY size
 
+$config{HAS_OPENSSL} =~ /OpenSSL (\S+) \d+ \S+ \d{4}/;
+$config{HAS_OPENSSL} = $1;
+
+# Minihack! Convert Cygwin to 'Cyg-Static' so i can
+# Keep my dynamic module experiments here for later
+# concideration!
+
+if ($config{OSNAME} =~ /CYGWIN/) {
+  $config{OSNAME} = "CYG-STATIC";
+}
+
 if ((!$config{OSNAME}) || ($config{OSNAME} eq "")) {
   chomp($config{OSNAME} = `/usr/bin/uname`);
   if ((!$config{OSNAME}) || ($config{OSNAME} eq "")){
@@ -84,6 +99,28 @@ if ($arg eq "-update") {
   }
 }
 
+if ($arg eq "-modupdate") {
+  # Does the cache file exist?
+  if (!getcache()) {
+    # No, No it doesn't.. *BASH*
+    print "You have not run ./configure before. Please do this before trying to run the update script.\n";
+    exit 0;
+  } else {
+    # We've Loaded the cache file and all our variables..
+    print "Updating Files..\n";
+    getosflags();
+    $has_epoll = $config{HAS_EPOLL};
+    $has_kqueue = $config{HAS_KQUEUE};
+    if ($config{STATIC_LINK} eq "yes") {
+      write_static_modules_makefile();
+    } else {
+      write_dynamic_modules_makefile();
+    }
+    print "Complete.\n";
+    exit;
+  }
+}
+
 print "Checking for cache from previous configure...\n";
 getcache();
 print "Checking operating system version...\n";
@@ -164,13 +201,31 @@ if ($has_epoll) {
 print "yes\n" if $has_epoll == 1;
 print "no\n" if $has_epoll == 0;
 
-if ($config{OSNAME} =~ /CYGWIN/) {
+if (($config{OSNAME} =~ /CYGWIN/) || ($config{OSNAME} eq "CYG-STATIC")) {
        $config{HAS_STRLCPY} = "true";
 }
 
 $config{HAS_EPOLL} = $has_epoll;
 $config{HAS_KQUEUE} = $has_kqueue; 
 
+printf "Checking for libgnutls... ";
+if (($config{HAS_GNUTLS}) && (($config{HAS_GNUTLS} >= 1.2) || ($config{HAS_GNUTLS} eq "y"))) {
+       print "yes\n";
+       $config{HAS_GNUTLS} = "y";
+} else {
+       print "no\n";
+       $config{HAS_GNUTLS} = "n";
+}
+
+printf "Checking for openssl... ";
+if (($config{HAS_OPENSSL}) && (($config{HAS_OPENSSL} >= 0.8) || ($config{HAS_OPENSSL} eq "y"))) {
+       print "yes\n";
+       $config{HAS_OPENSSL} = "y";
+} else {
+       print "no\n";
+       $config{HAS_OPENSSL} = "n";
+}
+
 ################################################################################
 #                          BEGIN INTERACTIVE PART                              #
 ################################################################################
@@ -259,6 +314,25 @@ if (!$chose_hiperf)
 yesno(THREADED_DNS,"Would you like to enable the experimental multi-threaded DNS lookup?");
 print "\n";
 
+if (($config{HAS_GNUTLS} eq "y") && ($config{HAS_OPENSSL} eq "y")) {
+       print "I have detected both GnuTLS and OpenSSL on your system.\n";
+       print "I will default to GnuTLS. If you wish to use OpenSSL\n";
+       print "instead, you should enable the OpenSSL module yourself\n";
+       print "by copying it from src/modules/extra to src/modules.\n\n";
+}
+
+if ($config{HAS_GNUTLS} eq "y") {
+       yesno(USE_GNUTLS, "Would you like to enable SSL Support?");
+       if ($config{USE_GNUTLS} eq "y") {
+               print "\nUsing GnuTLS SSL module.\n";
+       }
+} elsif ($config{HAS_OPENSSL} eq "y") {
+       yesno(USE_OPENSSL, "Would you like to enable SSL Support?");
+       if ($config{USE_OPENSSL} eq "y") {
+               print "\nUsing OpenSSL SSL module.\nYou will get better performance if you move to GnuTLS in the future.\n";
+       }
+}
+
 print "\nThe following questions will ask you for various figures relating\n";
 print "To your IRCd install. Please note that these should usually be left\n";
 print "as defaults unless you have a real reason to change them. If they\n";
@@ -521,29 +595,84 @@ print "\033[0mMax kick length:\033[1;32m\t\t$config{MAX_KICK}\n";
 print "\033[0mMax name length:\033[1;32m\t\t$config{MAX_GECOS}\n";
 print "\033[0mMax away length:\033[1;32m\t\t$config{MAX_AWAY}\n";
 print "\033[0mGCC Version Found:\033[1;32m\t\t$config{GCCVER}.$config{GCC34}\n";
-print "\033[0mOptimatizaton Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
+print "\033[0mOptimization Flag:\033[1;32m\t\t$config{OPTIMISATI}\033[0m\n";
 print "\033[0mCompiler program:\033[1;32m\t\t$config{CC}\033[0m\n";
 print "\033[0mStatic modules:\033[1;32m\t\t\t$config{STATIC_LINK}\033[0m\n";
-print "\033[0mMultithread DNS:\033[1;32m\t\t$config{THREADED_DNS}\033[0m\n\n";
+print "\033[0mMultithread DNS:\033[1;32m\t\t$config{THREADED_DNS}\033[0m\n";
+print "\033[0mGnuTLS Support:\033[1;32m\t\t\t$config{USE_GNUTLS}\033[0m\n";
+print "\033[0mOpenSSL Support:\033[1;32m\t\t$config{USE_OPENSSL}\033[0m\n\n";
+
+if ($config{USE_GNUTLS} eq "y") {
+       system("ln -s src/modules/extra/m_ssl_gnutls.cpp src/modules/m_ssl_gnutls.cpp");
+       getmodules();
+       $failed = 0;
+       open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
+       close(TMP);
+       open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
+       close(TMP);
+       if ($failed) {
+               print "SSL Certificates Not found, Generating.. \n\n
+*************************************************************
+* Generating the Private Key may take some time, go grab a  *
+* Coffee. Even better, to generate some more entropy if it  *
+* is taking a while, open another console and type du / a   *
+* few times and get that HD going :) Then answer the        *
+* Questions which follow. If you are unsure, just hit enter *
+*************************************************************\n\n";
+               system("certtool --generate-privkey --outfile key.pem");
+               system("certtool --generate-self-signed --load-privkey key.pem --outfile cert.pem");
+               print "\nCertificate generation complete, copying to config directory... ";
+               system("mv key.pem $config{CONFIG_DIR}/key.pem");
+               system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
+               print "Done.\n\n";
+       } else {
+               print "SSL Certificates found, skipping.\n\n"
+       }       
+} elsif ($config{USE_OPENSSL} eq "y") {
+       system("ln -s src/modules/extra/m_ssl_openssl.cpp src/modules/m_ssl_openssl.cpp");
+       getmodules();
+       $failed = 0;
+       open(TMP, "<$config{CONFIG_DIR}/key.pem") or $failed = 1;
+       close(TMP);
+       open(TMP, "<$config{CONFIG_DIR}/cert.pem") or $failed = 1;
+       close(TMP);
+       if ($failed) {
+               print "SSL Certificates Not found, Generating.. \n\n
+*************************************************************
+* Generating the certificates may take some time, go grab a *
+* coffee, or something.                                     *
+*************************************************************\n\n";
+               system("openssl req -x509 -nodes -newkey rsa:1024 -keyout key.pem -out cert.pem");
+               system("openssl dhparam -out dhparams.pem 1024");
+               print "\nCertificate generation complete, copying to config directory... ";
+               system("mv key.pem $config{CONFIG_DIR}/key.pem");
+               system("mv cert.pem $config{CONFIG_DIR}/cert.pem");
+               system("mv dhparams.pem $config{CONFIG_DIR}/dhparams.pem");
+               print "Done.\n\n";
+       } else {
+               print "SSL Certificates found, skipping.\n\n"
+       }
+}
+if (($config{USE_GNUTLS} eq "n") && ($config{USE_OPENSSL} eq "n")) {
+       print "Skipping SSL Certificate generation, SSL support is not available.\n\n";
+}
 
+getosflags();
 makecache();
 writefiles();
 
 print "\n\n";
 print "To build your server with these settings, please type '\033[1;32m$config{MAKEPROG}\033[0m' now.\n";
+if (($config{USE_GNUTLS} eq "y") || ($config{USE_OPENSSL} eq "y")) {
+       print "Please remember that to enable \033[1;32mSSL support\033[0m you must\n";
+       print "load the required modules in your config. This configure process\n";
+       print "has just prepared these modules to be compiled for you, and has not\n";
+       print "configured them to be compiled into the core of the ircd.\n";
+}
 print "*** \033[1;32mRemember to edit your configuration files!!!\033[0m ***\n\n\n";
 if (($config{OSNAME} eq "OpenBSD") && ($config{CC} ne "eg++")) {
        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";
 }
-if ($config{OSNAME} =~ /CYGWIN/) {
-       print <<FOO;
-\033[1;32mWARNING!\033[0m CYGWIN does not properly support shared modules,
-so modules will be compiled statically into the core of the ircd. The modules
-will act like they are being loaded from disk and being unloaded from RAM,
-however they are in fact being enabled and disabled similar to features in
-other ircds.
-FOO
-}
 
 if ($config{GCCVER} < "3") {
        print <<FOO2;
@@ -639,7 +768,7 @@ sub dir_check {
 sub getosflags {
   if ($config{OSNAME} =~ /BSD$/) {
     $config{LDLIBS} = "-Ldl -lstdc++";
-    $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Wall -Woverloaded-virtual $config{OPTIMISATI}";
+    $config{FLAGS}  = "-fPIC -frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
     $config{MAKEPROG} = "gmake";
     if ($config{OSNAME} eq "OpenBSD") {
        chomp($foo = `eg++ -dumpversion | cut -c 1`);
@@ -654,10 +783,15 @@ sub getosflags {
     }
   } else {
     $config{LDLIBS} = "-ldl -lstdc++";
-    $config{FLAGS}  = "-fPIC -frtti $OPTIMISATI -Wall -Woverloaded-virtual $config{OPTIMISATI}";
+    $config{FLAGS}  = "-fPIC -frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
     $config{MAKEPROG} = "make";
     if ($config{OSNAME} =~ /CYGWIN/) {
-       $config{FLAGS}  = "-frtti $OPTIMISATI -Wall -Woverloaded-virtual $config{OPTIMISATI}";
+       $config{FLAGS}  = "-frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
+       $config{LDLIBS} = "";
+       $config{MAKEPROG} = "/usr/bin/make";
+       $config{MAKEORDER} = "ircd mods config bininst";
+    } elsif ($config{OSNAME} eq "CYG-STATIC") {
+       $config{FLAGS} = "-frtti -Wall -Woverloaded-virtual $config{OPTIMISATI}";
        $config{LDLIBS} = "";
        $config{MAKEPROG} = "/usr/bin/make";
        $config{MAKEORDER} = "mods ircd config bininst";
@@ -744,6 +878,10 @@ EOF
     print FILEHANDLE "#define IS_CYGWIN\n";
     print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE   1024\n#endif\n";
   }
+  if ($config{OSNAME} eq "CYG-STATIC") {
+    print FILEHANDLE "#ifndef FD_SETSIZE\n#define FD_SETSIZE    1024\n#endif\n";
+  }
+
   if ($config{STATIC_LINK} eq "yes") {
     print FILEHANDLE "#define STATIC_LINK\n";
   }
@@ -787,7 +925,7 @@ EOF
   my $modules = "";
   foreach $i (@modlist)
   {
-    if ($config{OSNAME} =~ /CYGWIN/) {
+    if ($config{STATIC_LINK} eq "yes") {
         $modules .= "m_".$i.".o ";
     }
     else {
@@ -846,94 +984,18 @@ EOF
   # Make inspircd executable!
   chmod 0744, 'inspircd';
 
-  if ($config{OSNAME} =~ /CYGWIN/) {
+  if ($config{STATIC_LINK} eq "yes") {
        print "Writing static-build \033[1;32msrc/Makefile\033[0m\n";
        write_static_makefile();
-  }
-  else {
+       write_static_modules_makefile();
+  } elsif ($config{OSNAME} =~ /CYGWIN/) {
+       print "Writing cygwin-build \033[1;32msrc/Makefile\033[0m\n";
+       write_static_makefile();
+       write_dynamic_modules_makefile();
+  } else {
        print "Writing dynamic-build \033[1;32msrc/Makefile\033[0m\n";
        write_dynamic_makefile();
-  }
-
-
-  # Modules Makefile..
-  print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
-  open(FILEHANDLE, ">src/modules/Makefile");
-  print FILEHANDLE <<EOF;
-# (C) ChatSpike development team
-# Makefile by <Craig\@ChatSpike.net>
-# Many Thanks to Andrew Church <achurch\@achurch.org>
-#    for assisting with making this work right.
-#
-# Automatically Generated by ./configure to add a modules
-# please run ./configure --update
-
-all: \$(MODULES)
-
-EOF
-
-  # Create a Modules List..
-  my $modules = "";
-  my $cmflags = "";
-  my $liflags = "";
-  if ($config{OSNAME} =~ /CYGWIN/) {
-     open(MODLIST,">include/modlist.h");
-     print MODLIST <<HEADER;
-// Generated automatically by configure. DO NOT EDIT!
-
-#ifndef __SYMBOLS__H_CONFIGURED__
-#define __SYMBOLS__H_CONFIGURED__
-
-HEADER
-     foreach $i (@modlist) {
-       if ($i !~ /_static$/) {
-               print MODLIST "extern \"C\" void * $i\_init (void);\n";
-       }
-     }
-     print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
-  }
-  foreach $i (@modlist)
-  {
-    if ($i !~ /_static$/) {
-     $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
-     $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
-     if ($config{OSNAME} =~ /CYGWIN/) {
-        print FILEHANDLE <<EOCHEESE;
-m_$i.o: m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h
-       \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i\_static.cpp
-       mv m_$i\_static.o ../m_$i.o
-
-EOCHEESE
-        print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
-        open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
-        open(MUNGED,">src/modules/m_".$i."_static.cpp") or die("Could not create m_".$i."_static.cpp");
-        while (chomp($a = <MODULE>)) { 
-               $a =~ s/init_module/$i\_init/g;
-               $a =~ s/Srv/$i\Srv/g;
-               print MUNGED "$a\n";
-        }
-        close(MODULE);
-        close(MUNGED);
-        print MODLIST <<EOENT;
-{"m_$i.so",\&$i\_init},
-EOENT
-        print "done\n";
-     }
-     else {
-         print FILEHANDLE <<EOCHEESE;
-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/inspircd_io.h
-       \$(CC) -pipe -I../../include \$(FLAGS) $cmflags -export-dynamic -c m_$i.cpp
-       \$(CC) \$(FLAGS) -shared $liflags -o m_$i.so m_$i.o
-       \@-rm -f \$(MODPATH)/m_$i.so
-       install -C -v -m 0700 m_$i.so \$(MODPATH)
-
-EOCHEESE
-      }
-   }
-  }
-  if ($config{OSNAME} =~ /CYGWIN/) {
-     print MODLIST "{0}};\n\n#endif\n";
-     close(MODLIST);
+       write_dynamic_modules_makefile();
   }
 }
 
@@ -993,6 +1055,154 @@ sub yesno {
        return;
 }
 
+sub write_static_modules_makefile {
+  # Modules Makefile..
+  print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
+  open(FILEHANDLE, ">src/modules/Makefile");
+
+###
+# Module Makefile Header
+###
+  print FILEHANDLE <<EOF;
+# (C) ChatSpike development team
+# Makefile by <Craig\@ChatSpike.net>
+# Many Thanks to Andrew Church <achurch\@achurch.org>
+#    for assisting with making this work right.
+#
+# Automatically Generated by ./configure to add a modules
+# please run ./configure --update
+
+all: \$(MODULES)
+
+EOF
+###
+# End Module Makefile Header
+###
+
+# Create a Modules List..
+my $modules = "";
+my $cmflags = "";
+my $liflags = "";
+
+open(MODLIST,">include/modlist.h");
+
+###
+# Include File Header
+###
+print MODLIST <<HEADER;
+// Generated automatically by configure. DO NOT EDIT!
+
+#ifndef __SYMBOLS__H_CONFIGURED__
+#define __SYMBOLS__H_CONFIGURED__
+
+HEADER
+###
+# End Include File Header
+###
+
+# Place Module List into Include
+foreach $i (@modlist) {
+       if ($i !~ /_static$/) {
+               print MODLIST "extern \"C\" void * $i\_init (void);\n";
+       }
+}
+print MODLIST "\nstruct {const char *name; initfunc *value; } modsyms[] = {\n";
+
+###
+# Build Module Crap
+###
+foreach $i (@modlist)
+{
+       if ($i !~ /_static$/) {
+               $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
+               $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
+
+               ###
+               # Write Entry to the Makefile
+               ###
+               print FILEHANDLE <<EOCHEESE;
+m_$i.o: m_$i\_static.cpp ../../include/modules.h ../../include/users.h ../../include/channels.h ../../include/base.h
+       \$(CC) -pipe -I../../include \$(FLAGS) $flags -export-dynamic -c m_$i\_static.cpp
+       mv m_$i\_static.o ../m_$i.o
+
+EOCHEESE
+               ###
+               # End Write Entry to the MakeFile
+               ###
+               print "Configuring module [\033[1;32mm_$i.so\033[0m] for static linking... ";
+               open(MODULE,"<src/modules/m_".$i.".cpp") or die("Could not open m_".$i.".cpp");
+               open(MUNGED,">src/modules/m_".$i."_static.cpp") or die("Could not create m_".$i."_static.cpp");
+               while (chomp($a = <MODULE>)) { 
+                       $a =~ s/init_module/$i\_init/g;
+                       $a =~ s/Srv/$i\Srv/g;
+                       print MUNGED "$a\n";
+               }
+               close(MODULE);
+               close(MUNGED);
+               print MODLIST <<EOENT;
+{"m_$i.so",\&$i\_init},
+EOENT
+               print "done\n";
+       }
+}
+print MODLIST "{0}};\n\n#endif\n";
+close(MODLIST);
+}
+
+sub write_dynamic_modules_makefile {
+  # Modules Makefile..
+  print "Writing \033[1;32msrc/modules/Makefile\033[0m\n";
+  open(FILEHANDLE, ">src/modules/Makefile");
+  my $extra = "";
+
+  if ($config{OSNAME} =~ /CYGWIN/) {
+       $extra = "../inspircd.dll.a";
+  }
+
+###
+# Module Makefile Header
+###
+  print FILEHANDLE <<EOF;
+# (C) ChatSpike development team
+# Makefile by <Craig\@ChatSpike.net>
+# Many Thanks to Andrew Church <achurch\@achurch.org>
+#    for assisting with making this work right.
+#
+# Automatically Generated by ./configure to add a modules
+# please run ./configure -update or ./configure -modupdate
+
+all: \$(MODULES)
+
+EOF
+###
+# End Module Makefile Header
+###
+
+# Create a Modules List..
+my $modules = "";
+my $cmflags = "";
+my $liflags = "";
+
+foreach $i (@modlist) {
+       ###
+       # Write Entry to the MakeFile
+       ###
+       $cmflags = getcompilerflags("src/modules/m_".$i.".cpp");
+       $liflags = getlinkerflags("src/modules/m_".$i.".cpp");
+       print FILEHANDLE <<EOCHEESE;
+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/inspircd_io.h
+       \$(CC) -pipe -I../../include \$(FLAGS) $cmflags -export-dynamic -c m_$i.cpp
+       \$(CC) \$(FLAGS) -shared $liflags -o m_$i.so m_$i.o $extra
+       \@-rm -f \$(MODPATH)/m_$i.so
+       install -v -m 0700 m_$i.so \$(MODPATH)
+
+EOCHEESE
+       ###
+       # End Write Entry to the MakeFile
+       ###
+}
+}
+
 
 sub write_static_makefile {
        open(FH,">src/Makefile") or die("Could not write src/Makefile!");
@@ -1016,17 +1226,43 @@ sub write_static_makefile {
 #
 # (C) ChatSpike development team
 # Makefile by <Craig\@ChatSpike.net>
-# Makefile version 2 (dynamically linked core) by <brain\@inspircd.org>
+# Makefile version 2 (statically linked core) by <brain\@inspircd.org>
 #
 
 CC = im a cheezeball
 
 CXXFLAGS = -I../include \${FLAGS}
 
+EOM
+###
+# This next section is for cygwin dynamic module builds.
+# Basically, what we do, is build the inspircd core as a library
+# then the main executable uses that. the library is capable of
+# loading / unloading the modules dynamically :)
+# Massive thanks to the guys on #cygwin @ irc.freenode.net for helping
+# make this work :)
+###
+
+if ($config{OSNAME} =~ /CYGWIN/) {
+       print FH <<EOM;
+all: 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 inspircd_io.o message.o $cmdobjs commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o helperfuncs.o inspircd.exe
+
+inspircd.exe: inspircd.dll.a
+       \$(CC) -o \$@ \$^
+
+inspircd.dll inspircd.dll.a: inspircd.o channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_io.o message.o $cmdobjs  commands.o dnsqueue.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
+       \$(CC) -shared -Wl,--out-implib=inspircd.dll.a -o inspircd.dll \$^
+EOM
+} else {
+       print FH <<EOM;
 all: 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 inspircd_io.o message.o $cmdobjs commands.o dnsqueue.o dynamic.o users.o modules.o wildcard.o helperfuncs.o \$(MODULES) inspircd.exe
 
 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
        \$(CC) -I../include \$(FLAGS) inspircd.cpp -o inspircd.exe \$(LDLIBS) channels.o mode.o xline.o inspstring.o dns.o base.o inspircd_io.o message.o $cmdobjs commands.o dnsqueue.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 \$(MODULES)
+EOM
+}
+
+print FH <<EOM;
 
 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
        \$(CC) -pipe -I../include \$(FLAGS) -export-dynamic -c cull_list.cpp