diff --git a/Modules/Platform/CYGWIN.cmake b/Modules/Platform/CYGWIN.cmake
index 386acf2f553eb602d023c348ba133ad6585575cb..89c3453241a3e6ea95d26687f039c3de7016d507 100644
--- a/Modules/Platform/CYGWIN.cmake
+++ b/Modules/Platform/CYGWIN.cmake
@@ -32,9 +32,9 @@ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
   "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 
 SET(CMAKE_C_LINK_EXECUTABLE
-  "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+  "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
 SET(CMAKE_CXX_LINK_EXECUTABLE
-  "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+  "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
 
 # Shared libraries on cygwin can be named with their version number.
 SET(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 1)
diff --git a/Modules/Platform/Windows-bcc32.cmake b/Modules/Platform/Windows-bcc32.cmake
index d921cb43e896370e83b82e61bac8cd36b4cc974f..7840473183de98022c4916c8f89512dfc502b32e 100644
--- a/Modules/Platform/Windows-bcc32.cmake
+++ b/Modules/Platform/Windows-bcc32.cmake
@@ -64,11 +64,15 @@ SET(CMAKE_C_COMPILE_OBJECT
 
 
 SET(CMAKE_C_LINK_EXECUTABLE
-    "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE}-e<TARGET> <LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}")
+  "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE}-e<TARGET> <LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}"
+  "implib -c -w <TARGET_IMPLIB> <TARGET>"
+  )
 
 
 SET(CMAKE_CXX_LINK_EXECUTABLE
-    "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> -e<TARGET> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}")
+  "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> -e<TARGET> <FLAGS> <LINK_LIBRARIES> <OBJECTS> ${CMAKE_END_TEMP_FILE}"
+  "implib -c -w <TARGET_IMPLIB> <TARGET>"
+  )
 
 SET (CMAKE_BUILD_TYPE Debug CACHE STRING 
      "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.")
diff --git a/Modules/Platform/Windows-cl.cmake b/Modules/Platform/Windows-cl.cmake
index 94cb64da6d7ed290f859ee6eb653ebc233b5d351..6c6cac20726c480691105dd5c3ef1aaf32e80c46 100644
--- a/Modules/Platform/Windows-cl.cmake
+++ b/Modules/Platform/Windows-cl.cmake
@@ -15,8 +15,7 @@ ENDIF(CMAKE_VERBOSE_MAKEFILE)
 # create a shared C++ library
 SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
   "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
-SET(CMAKE_CXX_CREATE_SHARED_MODULE
-  "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+SET(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
 
 # create a C shared library
 SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
@@ -40,10 +39,10 @@ SET(CMAKE_C_COMPILE_OBJECT
 
 
 SET(CMAKE_C_LINK_EXECUTABLE
-    "<CMAKE_C_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_C_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
 
 SET(CMAKE_CXX_LINK_EXECUTABLE
-    "<CMAKE_CXX_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+    "<CMAKE_CXX_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> <OBJECTS> /Fe<TARGET> /Fd<TARGET_PDB> -link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
 
 SET(CMAKE_C_CREATE_PREPROCESSED_SOURCE
     "<CMAKE_C_COMPILER> > <PREPROCESSED_SOURCE> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} <FLAGS> -E <SOURCE>${CMAKE_END_TEMP_FILE}")
diff --git a/Modules/Platform/Windows-gcc.cmake b/Modules/Platform/Windows-gcc.cmake
index 8a2cf985941d6e876bfbed2f866a5567679a370a..805b45126f17364109f1619c58c7225a8c749b97 100644
--- a/Modules/Platform/Windows-gcc.cmake
+++ b/Modules/Platform/Windows-gcc.cmake
@@ -39,9 +39,9 @@ SET(CMAKE_CXX_CREATE_SHARED_LIBRARY
   "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 
 SET(CMAKE_C_LINK_EXECUTABLE
-  "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+  "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
 SET(CMAKE_CXX_LINK_EXECUTABLE
-  "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+  "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
 
 # Initialize C link type selection flags.  These flags are used when
 # building a shared library, shared module, or executable that links
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index d270c77d3dbb82264659d101bc942634ad273e2a..5244b9f9cdae8abff3ac82bc46d66a63e1172e66 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -532,6 +532,20 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
           this->SetError(e.str().c_str());
           return false;
           }
+
+        // On DLL platforms an executable may also have an import
+        // library.  Install it to the archive destination if it
+        // exists.
+        if(dll_platform && archive_destination)
+          {
+          // The import library uses the ARCHIVE properties.
+          this->Makefile->AddInstallGenerator(
+            new cmInstallTargetGenerator(target, archive_dest.c_str(), true,
+                                         archive_permissions.c_str(),
+                                         archive_configurations,
+                                         archive_component.c_str(),
+                                         true));
+          }
         }
         break;
       default:
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 3acabec40b6287f666fd9fa289ab2b952a725974..fd92eab220b0f2fc48a9ff0ba8b159bc9e046ba4 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -208,11 +208,21 @@ cmInstallTargetGenerator
       {
       std::string targetName;
       std::string targetNameReal;
+      std::string targetNameImport;
       std::string targetNamePDB;
       target->GetExecutableNames(targetName, targetNameReal,
-                                 targetNamePDB, i->c_str());
-      // Use the canonical name.
-      fname += targetName;
+                                 targetNameImport, targetNamePDB,
+                                 i->c_str());
+      if(this->ImportLibrary)
+        {
+        // Use the import library name.
+        fname += targetNameImport;
+        }
+      else
+        {
+        // Use the canonical name.
+        fname += targetName;
+        }
       }
     else
       {
@@ -259,11 +269,21 @@ std::string cmInstallTargetGenerator::GetScriptReference(cmTarget* target,
       {
       std::string targetName;
       std::string targetNameReal;
+      std::string targetNameImport;
       std::string targetNamePDB;
       target->GetExecutableNames(targetName, targetNameReal,
-                                 targetNamePDB, this->ConfigurationName);
-      // Use the canonical name.
-      return targetName;
+                                 targetNameImport, targetNamePDB,
+                                 this->ConfigurationName);
+      if(this->ImportLibrary)
+        {
+        // Use the import library name.
+        return targetNameImport;
+        }
+      else
+        {
+        // Use the canonical name.
+        return targetName;
+        }
       }
     else
       {
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 008061a34337859449aa964aa4bbaf081c916880..2b8f3466f9c4c04368c7fbad4fc365121ee35572 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1645,8 +1645,9 @@ cmLocalUnixMakefileGenerator3
     objectName = cmSystemTools::GetFilenameName(objectName.c_str());
     std::string targetName;
     std::string targetNameReal;
+    std::string targetNameImport;
     std::string targetNamePDB;
-    target.GetExecutableNames(targetName, targetNameReal,
+    target.GetExecutableNames(targetName, targetNameReal, targetNameImport,
                               targetNamePDB, this->ConfigurationName.c_str());
     std::string obj;
     if ( target.GetPropertyAsBool("MACOSX_BUNDLE") )
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 3a72de69906255e8322a3481eecd1be17cc93b29..40ba47390396a77a816d476c4633ee1fd8fbcbd4 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -1221,7 +1221,9 @@ void cmLocalVisualStudio6Generator
   std::string targetImplibFlagRelease;
   std::string targetImplibFlagMinSizeRel;
   std::string targetImplibFlagRelWithDebInfo;
-  if(target.GetType() == cmTarget::SHARED_LIBRARY)
+  if(target.GetType() == cmTarget::SHARED_LIBRARY ||
+     target.GetType() == cmTarget::MODULE_LIBRARY ||
+     target.GetType() == cmTarget::EXECUTABLE)
     {
     std::string fullPathImpDebug = target.GetDirectory("Debug", true);
     std::string fullPathImpRelease = target.GetDirectory("Release", true);
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index e627f0d6a1cda10b6a097ed0e0d44b374e3e6cb4..71a1e0d7d8f95d64a4de7887f644d9dae8a41cd2 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -733,17 +733,6 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     target.GetLibraryNames(targetName, targetNameSO, targetNameFull,
                            targetNameImport, targetNamePDB, configName);
 
-    // VS does not distinguish between shared libraries and module
-    // libraries so it still wants to be given the name of an import
-    // library for modules.
-    if(targetNameImport.empty() &&
-       target.GetType() == cmTarget::MODULE_LIBRARY)
-      {
-      targetNameImport =
-        cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
-      targetNameImport += ".lib";
-      }
-
     // Compute the link library and directory information.
     std::vector<cmStdString> linkLibs;
     std::vector<cmStdString> linkDirs;
@@ -816,9 +805,10 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     {
     std::string targetName;
     std::string targetNameFull;
+    std::string targetNameImport;
     std::string targetNamePDB;
     target.GetExecutableNames(targetName, targetNameFull,
-                              targetNamePDB, configName);
+                              targetNameImport, targetNamePDB, configName);
 
     // Compute the link library and directory information.
     std::vector<cmStdString> linkLibs;
@@ -886,7 +876,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       {
       fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
       }
-    fout << "/>\n";
+    temp = target.GetDirectory(configName, true);
+    temp += "/";
+    temp += targetNameImport;
+    fout << "\t\t\t\tImportLibrary=\""
+         << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
     break;
     }
     case cmTarget::UTILITY:
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 06b054a7d8006144e2c166b66bf2446378fdb568..241445800593bc47b3ff528cd433e07e4bc5dcce 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -110,9 +110,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   // Get the name of the executable to generate.
   std::string targetName;
   std::string targetNameReal;
+  std::string targetNameImport;
   std::string targetNamePDB;
   this->Target->GetExecutableNames
-    (targetName, targetNameReal, targetNamePDB,
+    (targetName, targetNameReal, targetNameImport, targetNamePDB,
      this->LocalGenerator->ConfigurationName.c_str());
 
   // Construct the full path version of the names.
@@ -167,6 +168,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
                                   false, false, false);
     }
 #endif
+  std::string outpathImp;
   if(relink)
     {
     outpath = this->Makefile->GetStartOutputDirectory();
@@ -174,10 +176,23 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     outpath += "/CMakeRelink.dir";
     cmSystemTools::MakeDirectory(outpath.c_str());
     outpath += "/";
+    if(!targetNameImport.empty())
+      {
+      outpathImp = outpath;
+      }
+    }
+  else
+    {
+    if(!targetNameImport.empty())
+      {
+      outpathImp = this->Target->GetDirectory(0, true);
+      outpathImp += "/";
+      }
     }
   std::string targetFullPath = outpath + targetName;
   std::string targetFullPathReal = outpath + targetNameReal;
   std::string targetFullPathPDB = outpath + targetNamePDB;
+  std::string targetFullPathImport = outpathImp + targetNameImport;
   std::string targetOutPathPDB = 
     this->Convert(targetFullPathPDB.c_str(),
                   cmLocalGenerator::FULL,
@@ -191,7 +206,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     this->Convert(targetFullPathReal.c_str(),
                   cmLocalGenerator::START_OUTPUT,
                   cmLocalGenerator::SHELL);
-  
+  std::string targetOutPathImport =
+    this->Convert(targetFullPathImport.c_str(),
+                  cmLocalGenerator::START_OUTPUT,
+                  cmLocalGenerator::SHELL);
+
   // Get the language to use for linking this executable.
   const char* linkLanguage =
     this->Target->GetLinkerLanguage(this->GlobalGenerator);
@@ -258,14 +277,16 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   {
   std::string cleanName;
   std::string cleanRealName;
+  std::string cleanImportName;
   std::string cleanPDBName;
   this->Target->GetExecutableCleanNames
-    (cleanName, cleanRealName, cleanPDBName,
+    (cleanName, cleanRealName, cleanImportName, cleanPDBName,
      this->LocalGenerator->ConfigurationName.c_str());
 
   std::string cleanFullName = outpath + cleanName;
   std::string cleanFullRealName = outpath + cleanRealName;
   std::string cleanFullPDBName = outpath + cleanPDBName;
+  std::string cleanFullImportName = outpathImp + cleanImportName;
   exeCleanFiles.push_back(this->Convert(cleanFullName.c_str(),
                                         cmLocalGenerator::START_OUTPUT,
                                         cmLocalGenerator::UNCHANGED));
@@ -282,6 +303,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
                                           cmLocalGenerator::START_OUTPUT,
                                           cmLocalGenerator::UNCHANGED));
     }
+  if(!cleanImportName.empty())
+    {
+    exeCleanFiles.push_back(this->Convert(cleanFullImportName.c_str(),
+                                          cmLocalGenerator::START_OUTPUT,
+                                          cmLocalGenerator::UNCHANGED));
+    }
 
   // List the PDB for cleaning only when the whole target is
   // cleaned.  We do not want to delete the .pdb file just before
@@ -394,11 +421,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   vars.Flags = flags.c_str();
   vars.LinkFlags = linkFlags.c_str();
   // Expand placeholders in the commands.
+  this->LocalGenerator->TargetImplib = targetOutPathImport;
   for(std::vector<std::string>::iterator i = commands.begin();
       i != commands.end(); ++i)
     {
     this->LocalGenerator->ExpandRuleVariables(*i, vars);
     }
+  this->LocalGenerator->TargetImplib = "";
 
   // Write the build rule.
   this->LocalGenerator->WriteMakeRule(*this->BuildFileStream,
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index d1398a182d23ae6f07f8be8a8e894fba0b2c2df3..717b0ddc411789ea4520ce2d58368027afffc511 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -341,10 +341,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
           cmLocalGenerator::START_OUTPUT,
           cmLocalGenerator::UNCHANGED));
       }
-    if(!targetNameImport.empty() &&
-       targetNameImport != targetName &&
-       targetNameImport != targetNameReal &&
-       targetNameImport != targetNameSO)
+    if(!targetNameImport.empty())
       {
       libCleanFiles.push_back(this->Convert(targetFullPathImport.c_str(),
           cmLocalGenerator::START_OUTPUT,
@@ -401,11 +398,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
           cmLocalGenerator::START_OUTPUT,
           cmLocalGenerator::UNCHANGED));
       }
-    if(!cleanImportName.empty() &&
-      cleanImportName != cleanStaticName &&
-      cleanImportName != cleanSharedSOName &&
-      cleanImportName != cleanSharedRealName &&
-      cleanImportName != cleanSharedName)
+    if(!cleanImportName.empty())
       {
       libCleanFiles.push_back(this->Convert(cleanFullImportName.c_str(),
           cmLocalGenerator::START_OUTPUT,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 45e71d04ff9956999768f45e6a97c463a81cd833..ef4a07ee07afb34d574505486cbda7dcb59981ab 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -37,6 +37,7 @@ cmTarget::cmTarget()
   this->LinkLibrariesAnalyzed = false;
   this->LinkDirectoriesComputed = false;
   this->HaveInstallRule = false;
+  this->DLLPlatform = false;
 
 }
 
@@ -335,6 +336,11 @@ void cmTarget::SetMakefile(cmMakefile* mf)
   // set the cmake instance of the properties
   this->Properties.SetCMakeInstance(mf->GetCMakeInstance());
 
+  // Check whether this is a DLL platform.
+  this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
+                       this->Makefile->IsOn("CYGWIN") ||
+                       this->Makefile->IsOn("MINGW"));
+
   // Setup default property values.
   this->SetPropertyDefault("INSTALL_NAME_DIR", "");
   this->SetPropertyDefault("INSTALL_RPATH", "");
@@ -1427,9 +1433,13 @@ const char* cmTarget::GetSuffixVariableInternal(TargetType type,
               ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
               : "CMAKE_SHARED_LIBRARY_SUFFIX");
     case cmTarget::MODULE_LIBRARY:
-      return "CMAKE_SHARED_MODULE_SUFFIX";
+      return (implib
+              ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
+              : "CMAKE_SHARED_MODULE_SUFFIX");
     case cmTarget::EXECUTABLE:
-      return "CMAKE_EXECUTABLE_SUFFIX";
+      return (implib
+              ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
+              : "CMAKE_EXECUTABLE_SUFFIX");
     case cmTarget::UTILITY:
     case cmTarget::GLOBAL_TARGET:
     case cmTarget::INSTALL_FILES:
@@ -1453,8 +1463,11 @@ const char* cmTarget::GetPrefixVariableInternal(TargetType type,
               ? "CMAKE_IMPORT_LIBRARY_PREFIX"
               : "CMAKE_SHARED_LIBRARY_PREFIX");
     case cmTarget::MODULE_LIBRARY:
-      return "CMAKE_SHARED_MODULE_PREFIX";
+      return (implib
+              ? "CMAKE_IMPORT_LIBRARY_PREFIX"
+              : "CMAKE_SHARED_MODULE_PREFIX");
     case cmTarget::EXECUTABLE:
+      return (implib? "CMAKE_IMPORT_LIBRARY_PREFIX" : "");
     case cmTarget::UTILITY:
     case cmTarget::GLOBAL_TARGET:
     case cmTarget::INSTALL_FILES:
@@ -1545,8 +1558,11 @@ void cmTarget::GetFullNameInternal(TargetType type,
     return;
     }
 
-  // The implib option is only allowed for shared libraries.
-  if(type != cmTarget::SHARED_LIBRARY)
+  // The implib option is only allowed for shared libraries, module
+  // libraries, and executables.
+  if(type != cmTarget::SHARED_LIBRARY &&
+     type != cmTarget::MODULE_LIBRARY &&
+     type != cmTarget::EXECUTABLE)
     {
     implib = false;
     }
@@ -1769,7 +1785,8 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
 #endif
 
   // The import library name.
-  if(type == cmTarget::SHARED_LIBRARY)
+  if(type == cmTarget::SHARED_LIBRARY ||
+     type == cmTarget::MODULE_LIBRARY)
     {
     impName = this->GetFullNameInternal(type, config, true);
     }
@@ -1784,26 +1801,29 @@ void cmTarget::GetLibraryNamesInternal(std::string& name,
 
 void cmTarget::GetExecutableNames(std::string& name,
                                   std::string& realName,
+                                  std::string& impName,
                                   std::string& pdbName,
                                   const char* config)
 {
   // Get the names based on the real type of the executable.
-  this->GetExecutableNamesInternal(name, realName, pdbName,
+  this->GetExecutableNamesInternal(name, realName, impName, pdbName,
                                    this->GetType(), config);
 }
 
 void cmTarget::GetExecutableCleanNames(std::string& name,
                                        std::string& realName,
+                                       std::string& impName,
                                        std::string& pdbName,
                                        const char* config)
 {
   // Get the name and versioned name of this executable.
-  this->GetExecutableNamesInternal(name, realName, pdbName,
+  this->GetExecutableNamesInternal(name, realName, impName, pdbName,
                                    cmTarget::EXECUTABLE, config);
 }
 
 void cmTarget::GetExecutableNamesInternal(std::string& name,
                                           std::string& realName,
+                                          std::string& impName,
                                           std::string& pdbName,
                                           TargetType type,
                                           const char* config)
@@ -1845,6 +1865,9 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
   realName += suffix;
 #endif
 
+  // The import library name.
+  impName = this->GetFullNameInternal(type, config, true);
+
   // The program database file name.
   pdbName = prefix+base+".pdb";
 }
@@ -1986,8 +2009,11 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char*)
 //----------------------------------------------------------------------------
 const char* cmTarget::GetOutputDir(bool implib)
 {
-  // The implib option is only allowed for shared libraries.
-  if(this->GetType() != cmTarget::SHARED_LIBRARY)
+  // The implib option is only allowed for shared libraries, module
+  // libraries, and executables.
+  if(this->GetType() != cmTarget::SHARED_LIBRARY &&
+     this->GetType() != cmTarget::MODULE_LIBRARY &&
+     this->GetType() != cmTarget::EXECUTABLE)
     {
     implib = false;
     }
@@ -2000,6 +2026,10 @@ const char* cmTarget::GetOutputDir(bool implib)
     {
     abort();
     }
+  if(implib && !this->DLLPlatform)
+    {
+    abort();
+    }
 
   // Select whether we are constructing the directory for the main
   // target or the import library.
@@ -2019,12 +2049,7 @@ const char* cmTarget::GetOutputDir(bool implib)
         // shared library is treated as a runtime target and the
         // corresponding import library is treated as an archive
         // target.
-
-        // Check whether this is a DLL platform.
-        bool dll_platform = (this->Makefile->IsOn("WIN32") ||
-                             this->Makefile->IsOn("CYGWIN") ||
-                             this->Makefile->IsOn("MINGW"));
-        if(dll_platform)
+        if(this->DLLPlatform)
           {
           if(implib)
             {
@@ -2048,12 +2073,28 @@ const char* cmTarget::GetOutputDir(bool implib)
       case cmTarget::MODULE_LIBRARY:
         {
         // Module libraries are always treated as library targets.
-        propertyName = "LIBRARY_OUTPUT_DIRECTORY";
+        // Module import libraries are treated as archive targets.
+        if(implib)
+          {
+          propertyName = "ARCHIVE_OUTPUT_DIRECTORY";
+          }
+        else
+          {
+          propertyName = "LIBRARY_OUTPUT_DIRECTORY";
+          }
         } break;
       case cmTarget::EXECUTABLE:
         {
         // Executables are always treated as runtime targets.
-        propertyName = "RUNTIME_OUTPUT_DIRECTORY";
+        // Executable import libraries are treated as archive targets.
+        if(implib)
+          {
+          propertyName = "ARCHIVE_OUTPUT_DIRECTORY";
+          }
+        else
+          {
+          propertyName = "RUNTIME_OUTPUT_DIRECTORY";
+          }
         } break;
       default: break;
       }
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 6e446e057483d2da647e1be660012bb87d53c83a..028231a75cd8b34979073278baa03e37b4056751 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -228,6 +228,7 @@ public:
       that takes into account executable version numbers.  This should
       be called only on an executable target.  */
   void GetExecutableNames(std::string& name, std::string& realName,
+                          std::string& impName,
                           std::string& pdbName, const char* config);
 
   /** Get the names of the executable used to remove existing copies
@@ -235,6 +236,7 @@ public:
       during a clean step.  This should be called only on an
       executable target.  */
   void GetExecutableCleanNames(std::string& name, std::string& realName,
+                               std::string& impName,
                                std::string& pdbName, const char* config);
 
   /**
@@ -323,6 +325,7 @@ private:
                                const char* config);
   void GetExecutableNamesInternal(std::string& name,
                                   std::string& realName,
+                                  std::string& impName,
                                   std::string& pdbName,
                                   TargetType type,
                                   const char* config);
@@ -360,6 +363,7 @@ private:
   bool RecordDependencies; 
   cmPropertyMap Properties;
   LinkLibraryVectorType OriginalLinkLibraries;
+  bool DLLPlatform;
 
   // The cmMakefile instance that owns this target.  This should
   // always be set.
diff --git a/Templates/EXEHeader.dsptemplate b/Templates/EXEHeader.dsptemplate
index bd743d6b149c59d21d0ed1dae3a20a99615f3af0..90faf7784a68a823416d5cbab363953baf858a02 100644
--- a/Templates/EXEHeader.dsptemplate
+++ b/Templates/EXEHeader.dsptemplate
@@ -69,7 +69,7 @@ BSC32=bscmake.exe
 LINK32=link.exe
 # ADD BASE LINK32  /nologo /subsystem:console /machine:I386 /IGNORE:4089
 # ADD LINK32  /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
-# ADD LINK32 /out:"OUTPUT_DIRECTORY\Release\OUTPUT_NAME_RELEASE"
+# ADD LINK32 /out:"OUTPUT_DIRECTORY\Release\OUTPUT_NAME_RELEASE" TARGET_IMPLIB_FLAG_RELEASE
 CM_MULTILINE_OPTIONS_RELEASE
 
 CMAKE_CUSTOM_RULE_CODE
@@ -101,7 +101,7 @@ BSC32=bscmake.exe
 LINK32=link.exe
 # ADD BASE LINK32  /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089
 # ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089 TARGET_VERSION_FLAG
-# ADD LINK32 /out:"OUTPUT_DIRECTORY\Debug\OUTPUT_NAME_DEBUG"
+# ADD LINK32 /out:"OUTPUT_DIRECTORY\Debug\OUTPUT_NAME_DEBUG" TARGET_IMPLIB_FLAG_DEBUG
 CM_MULTILINE_OPTIONS_DEBUG
 
 CMAKE_CUSTOM_RULE_CODE
@@ -130,7 +130,7 @@ BSC32=bscmake.exe
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
 # ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
-# ADD LINK32 /out:"OUTPUT_DIRECTORY\MinSizeRel\OUTPUT_NAME_MINSIZEREL"
+# ADD LINK32 /out:"OUTPUT_DIRECTORY\MinSizeRel\OUTPUT_NAME_MINSIZEREL" TARGET_IMPLIB_FLAG_MINSIZEREL
 CM_MULTILINE_OPTIONS_MINSIZEREL
 
 CMAKE_CUSTOM_RULE_CODE
@@ -160,7 +160,7 @@ BSC32=bscmake.exe
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089
 # ADD LINK32  /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
-# ADD LINK32 /out:"OUTPUT_DIRECTORY\RelWithDebInfo\OUTPUT_NAME_RELWITHDEBINFO"
+# ADD LINK32 /out:"OUTPUT_DIRECTORY\RelWithDebInfo\OUTPUT_NAME_RELWITHDEBINFO" TARGET_IMPLIB_FLAG_RELWITHDEBINFO
 CM_MULTILINE_OPTIONS_RELWITHDEBINFO
 
 CMAKE_CUSTOM_RULE_CODE