From b155f3aa1c4bb503557bda801059e0b6a28898cf Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Mon, 16 Oct 2006 18:17:14 -0400
Subject: ENH: Adding image version number (major.minor) property to windows
 binaries.  Default is 0.0, but the VERSION target property may change the
 value.  Windows now has first-class support for dll and exe versioning.  This
 addresses bug#1219.

---
 Modules/Platform/CYGWIN.cmake                  | 16 ++++++++---
 Modules/Platform/Windows-cl.cmake              |  6 ++--
 Modules/Platform/Windows-gcc.cmake             | 16 ++++++++---
 Source/cmLocalGenerator.cxx                    | 22 +++++++++++++++
 Source/cmLocalGenerator.h                      |  2 ++
 Source/cmLocalVisualStudio6Generator.cxx       | 16 +++++++++++
 Source/cmLocalVisualStudio7Generator.cxx       | 13 +++++++++
 Source/cmLocalVisualStudio7Generator.h         |  1 +
 Source/cmMakefileExecutableTargetGenerator.cxx | 18 ++++++++++++
 Source/cmMakefileLibraryTargetGenerator.cxx    | 18 ++++++++++++
 Source/cmSetTargetPropertiesCommand.h          |  6 +++-
 Source/cmTarget.cxx                            | 38 +++++++++++++++++++++++++-
 Source/cmTarget.h                              |  5 ++++
 Templates/DLLHeader.dsptemplate                |  8 +++---
 Templates/EXEHeader.dsptemplate                |  8 +++---
 15 files changed, 172 insertions(+), 21 deletions(-)

diff --git a/Modules/Platform/CYGWIN.cmake b/Modules/Platform/CYGWIN.cmake
index fe34bfc..386acf2 100644
--- a/Modules/Platform/CYGWIN.cmake
+++ b/Modules/Platform/CYGWIN.cmake
@@ -18,15 +18,23 @@ SET(CMAKE_MODULE_EXISTS 1)
 SET(CMAKE_FIND_LIBRARY_PREFIXES "cyg" "lib")
 SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a")
 
+SET(CMAKE_GNULD_IMAGE_VERSION
+  "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>")
+
 SET(CMAKE_C_CREATE_SHARED_MODULE
-  "<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_C_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+  "<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_C_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 SET(CMAKE_CXX_CREATE_SHARED_MODULE
-  "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+  "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_MODULE_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 
 SET(CMAKE_C_CREATE_SHARED_LIBRARY
-  "<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> <OBJECTS> <LINK_LIBRARIES>")
+  "<CMAKE_C_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 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> <OBJECTS> <LINK_LIBRARIES>")
+  "<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>")
+SET(CMAKE_CXX_LINK_EXECUTABLE
+  "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> ${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-cl.cmake b/Modules/Platform/Windows-cl.cmake
index b723038..361dbbc 100644
--- a/Modules/Platform/Windows-cl.cmake
+++ b/Modules/Platform/Windows-cl.cmake
@@ -14,7 +14,7 @@ ELSE(CMAKE_VERBOSE_MAKEFILE)
 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> /PDB:<TARGET_PDB> /dll  <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+  "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
@@ -39,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 <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 /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 <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 /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 a5152b3..8a2cf98 100644
--- a/Modules/Platform/Windows-gcc.cmake
+++ b/Modules/Platform/Windows-gcc.cmake
@@ -25,15 +25,23 @@ IF(MINGW)
   SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
 ENDIF(MINGW)
 
+SET(CMAKE_GNULD_IMAGE_VERSION
+  "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>")
+
 SET(CMAKE_C_CREATE_SHARED_MODULE
-  "<CMAKE_C_COMPILER> <CMAKE_SHARED_MODULE_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_C_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+  "<CMAKE_C_COMPILER> <CMAKE_SHARED_MODULE_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_C_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 SET(CMAKE_CXX_CREATE_SHARED_MODULE
-  "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_MODULE_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+  "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_MODULE_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 
 SET(CMAKE_C_CREATE_SHARED_LIBRARY
-  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> <OBJECTS> <LINK_LIBRARIES>")
+  "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
 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> <OBJECTS> <LINK_LIBRARIES>")
+  "<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>")
+SET(CMAKE_CXX_LINK_EXECUTABLE
+  "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> ${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/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index d0fc68f..0b0594c 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -840,6 +840,28 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable,
       {
       return this->TargetImplib;
       }
+    if(variable == "TARGET_VERSION_MAJOR")
+      {
+      if(replaceValues.TargetVersionMajor)
+        {
+        return replaceValues.TargetVersionMajor;
+        }
+      else
+        {
+        return "0";
+        }
+      }
+    if(variable == "TARGET_VERSION_MINOR")
+      {
+      if(replaceValues.TargetVersionMinor)
+        {
+        return replaceValues.TargetVersionMinor;
+        }
+      else
+        {
+        return "0";
+        }
+      }
     if(replaceValues.Target)
       {
       if(variable == "TARGET_BASE")
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 53b4220..fc59ed5 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -185,6 +185,8 @@ public:
         memset(this, 0,  sizeof(*this));
       }
     const char* TargetPDB;
+    const char* TargetVersionMajor;
+    const char* TargetVersionMinor;
     const char* Language;
     const char* Objects;
     const char* Target;
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 4295ce8..a24b14b 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -1131,6 +1131,20 @@ void cmLocalVisualStudio6Generator
       }
     }
 
+  // Compute version number information.
+  std::string targetVersionFlag;
+  if(target.GetType() == cmTarget::EXECUTABLE ||
+     target.GetType() == cmTarget::SHARED_LIBRARY ||
+     target.GetType() == cmTarget::MODULE_LIBRARY)
+    {
+    int major;
+    int minor;
+    target.GetTargetVersion(major, minor);
+    cmOStringStream targetVersionStream;
+    targetVersionStream << "/version:" << major << "." << minor;
+    targetVersionFlag = targetVersionStream.str();
+    }
+
   // Compute the real name of the target.
   std::string outputName = 
     "(OUTPUT_NAME is for libraries and executables only)";
@@ -1279,6 +1293,8 @@ void cmLocalVisualStudio6Generator
 
     cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
                                  this->IncludeOptions.c_str());
+    cmSystemTools::ReplaceString(line, "TARGET_VERSION_FLAG",
+                                 targetVersionFlag.c_str());
     cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME",libName);
     // because LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH 
     // are already quoted in the template file,
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 0fbca35..262d92e 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -801,6 +801,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     temp += targetFullName;
     fout << "\t\t\t\tOutputFile=\""
          << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+    this->WriteTargetVersionAttribute(fout, target);
     for(std::map<cmStdString, cmStdString>::iterator i = flagMap.begin();
         i != flagMap.end(); ++i)
       {
@@ -885,6 +886,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     temp += targetFullName;
     fout << "\t\t\t\tOutputFile=\"" 
          << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+    this->WriteTargetVersionAttribute(fout, target);
     for(std::map<cmStdString, cmStdString>::iterator i = flagMap.begin();
         i != flagMap.end(); ++i)
       {
@@ -925,6 +927,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     }
 }
 
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7Generator
+::WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target)
+{
+  int major;
+  int minor;
+  target.GetTargetVersion(major, minor);
+  fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n";
+}
+
 void cmLocalVisualStudio7Generator
 ::OutputModuleDefinitionFile(std::ostream& fout,
                              cmTarget &target)
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index d52cc63..48dce0c 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -112,6 +112,7 @@ private:
                        const std::vector<std::string>& depends,
                        const std::vector<std::string>& outputs,
                        const char* extraFlags);
+  void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target);
 
   void WriteGroup(const cmSourceGroup *sg, 
                   cmTarget target, std::ostream &fout, 
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 65e2877..4b24a19a 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -372,6 +372,24 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   vars.Objects = buildObjs.c_str();
   vars.Target = targetOutPathReal.c_str();
   vars.TargetPDB = targetOutPathPDB.c_str();
+
+  // Setup the target version.
+  std::string targetVersionMajor;
+  std::string targetVersionMinor;
+  {
+  cmOStringStream majorStream;
+  cmOStringStream minorStream;
+  int major;
+  int minor;
+  this->Target->GetTargetVersion(major, minor);
+  majorStream << major;
+  minorStream << minor;
+  targetVersionMajor = majorStream.str();
+  targetVersionMinor = minorStream.str();
+  }
+  vars.TargetVersionMajor = targetVersionMajor.c_str();
+  vars.TargetVersionMinor = targetVersionMinor.c_str();
+
   std::string linkString = linklibs.str();
   vars.LinkLibraries = linkString.c_str();
   vars.Flags = flags.c_str();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index dc7d37d..d80fc7e 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -531,6 +531,24 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
   cleanObjs += ")";
   cmLocalGenerator::RuleVariables vars;
   vars.TargetPDB = targetOutPathPDB.c_str();
+
+  // Setup the target version.
+  std::string targetVersionMajor;
+  std::string targetVersionMinor;
+  {
+  cmOStringStream majorStream;
+  cmOStringStream minorStream;
+  int major;
+  int minor;
+  this->Target->GetTargetVersion(major, minor);
+  majorStream << major;
+  minorStream << minor;
+  targetVersionMajor = majorStream.str();
+  targetVersionMinor = minorStream.str();
+  }
+  vars.TargetVersionMajor = targetVersionMajor.c_str();
+  vars.TargetVersionMinor = targetVersionMinor.c_str();
+
   vars.Language = linkLanguage;
   vars.Objects = buildObjs.c_str();
   std::string objdir = cmake::GetCMakeFilesDirectoryPostSlash();
diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h
index 86cb41a..cf777a6 100644
--- a/Source/cmSetTargetPropertiesCommand.h
+++ b/Source/cmSetTargetPropertiesCommand.h
@@ -108,7 +108,11 @@ public:
         "the same version number. "
         "For executables VERSION can be used to specify the build version. "
         "When building or installing appropriate symlinks are created if "
-        "the platform supports symlinks.\n"
+        "the platform supports symlinks. "
+        "For shared libraries and executables on Windows the VERSION "
+        "attribute is parsed to extract a \"major.minor\" version number. "
+        "These numbers are used as the image version of the binary. "
+        "\n"
         "There are a few properties used to specify RPATH rules. "
         "INSTALL_RPATH is a semicolon-separated list specifying the rpath "
         "to use in installed targets (for platforms that support it). "
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 9ac85ee..18cce53 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -890,6 +890,29 @@ const char* cmTarget::GetLocation(const char* config)
   return this->Location.c_str();
 }
 
+//----------------------------------------------------------------------------
+void cmTarget::GetTargetVersion(int& major, int& minor)
+{
+  // Set the default values.
+  major = 0;
+  minor = 0;
+
+  // Look for a VERSION property.
+  if(const char* version = this->GetProperty("VERSION"))
+    {
+    // Try to parse the version number and store the results that were
+    // successfully parsed.
+    int parsed_major;
+    int parsed_minor;
+    switch(sscanf(version, "%d.%d", &parsed_major, &parsed_minor))
+      {
+      case 2: minor = parsed_minor; // no break!
+      case 1: major = parsed_major; // no break!
+      default: break;
+      }
+    }
+}
+
 const char *cmTarget::GetProperty(const char* prop)
 {
   // watch for special "computed" properties that are dependent on other
@@ -1442,16 +1465,29 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
     }
 #endif
 
+  // Get the components of the executable name.
+  std::string prefix;
+  std::string base;
+  std::string suffix;
+  this->GetFullNameInternal(type, config, false, prefix, base, suffix);
+
   // The executable name.
-  name = this->GetFullNameInternal(type, config, false);
+  name = prefix+base+suffix;
 
   // The executable's real name on disk.
+#if defined(__CYGWIN__)
+  realName = prefix+base;
+#else
   realName = name;
+#endif
   if(version)
     {
     realName += "-";
     realName += version;
     }
+#if defined(__CYGWIN__)
+  realName += suffix;
+#endif
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8b05958..dc39f80 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -176,6 +176,11 @@ public:
       target property.  */
   const char* GetLocation(const char* config);
 
+  /** Get the target major and minor version numbers interpreted from
+      the VERSION property.  Version 0 is returned if the property is
+      not set or cannot be parsed.  */
+  void GetTargetVersion(int& major, int& minor);
+
   /**
    * Trace through the source files in this target and add al source files
    * that they depend on, used by the visual studio generators
diff --git a/Templates/DLLHeader.dsptemplate b/Templates/DLLHeader.dsptemplate
index 7234a74..8d4413e 100644
--- a/Templates/DLLHeader.dsptemplate
+++ b/Templates/DLLHeader.dsptemplate
@@ -71,7 +71,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /dll /machine:I386
-# ADD LINK32 /nologo /dll /machine:I386 /out:"LIBRARY_OUTPUT_PATHRelease/OUTPUT_NAME_RELEASE"
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /machine:I386 /out:"LIBRARY_OUTPUT_PATHRelease/OUTPUT_NAME_RELEASE"
 CM_MULTILINE_OPTIONS_RELEASE
 
 CMAKE_CUSTOM_RULE_CODE
@@ -103,7 +103,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"LIBRARY_OUTPUT_PATHDebug/OUTPUT_NAME_DEBUG" /pdbtype:sept
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /debug /machine:I386 /out:"LIBRARY_OUTPUT_PATHDebug/OUTPUT_NAME_DEBUG" /pdbtype:sept
 CM_MULTILINE_OPTIONS_DEBUG
 
 CMAKE_CUSTOM_RULE_CODE
@@ -137,7 +137,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32  /nologo /dll /machine:I386 
-# ADD LINK32 /nologo /dll /machine:I386 /out:"LIBRARY_OUTPUT_PATHMinSizeRel/OUTPUT_NAME_MINSIZEREL"
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /machine:I386 /out:"LIBRARY_OUTPUT_PATHMinSizeRel/OUTPUT_NAME_MINSIZEREL"
 CM_MULTILINE_OPTIONS_MINSIZEREL
 
 CMAKE_CUSTOM_RULE_CODE
@@ -169,7 +169,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /dll /machine:I386 /pdbtype:sept
-# ADD LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept /out:"LIBRARY_OUTPUT_PATHRelWithDebInfo/OUTPUT_NAME_RELWITHDEBINFO"
+# ADD LINK32 /nologo /dll TARGET_VERSION_FLAG /debug /machine:I386 /pdbtype:sept /out:"LIBRARY_OUTPUT_PATHRelWithDebInfo/OUTPUT_NAME_RELWITHDEBINFO"
 CM_MULTILINE_OPTIONS_RELWITHDEBINFO
 
 CMAKE_CUSTOM_RULE_CODE
diff --git a/Templates/EXEHeader.dsptemplate b/Templates/EXEHeader.dsptemplate
index 518ec28..ed80c7a 100644
--- a/Templates/EXEHeader.dsptemplate
+++ b/Templates/EXEHeader.dsptemplate
@@ -68,7 +68,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32  /nologo /subsystem:console /machine:I386 /IGNORE:4089
-# ADD LINK32  /nologo /subsystem:console /machine:I386 /IGNORE:4089
+# ADD LINK32  /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
 # ADD LINK32 /out:"EXECUTABLE_OUTPUT_PATHRelease\OUTPUT_NAME_RELEASE"
 CM_MULTILINE_OPTIONS_RELEASE
 
@@ -100,7 +100,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 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
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /IGNORE:4089 TARGET_VERSION_FLAG
 # ADD LINK32 /out:"EXECUTABLE_OUTPUT_PATHDebug\OUTPUT_NAME_DEBUG"
 CM_MULTILINE_OPTIONS_DEBUG
 
@@ -129,7 +129,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
-# ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089
+# ADD LINK32 /nologo /subsystem:console /machine:I386 /IGNORE:4089 TARGET_VERSION_FLAG
 # ADD LINK32 /out:"EXECUTABLE_OUTPUT_PATHMinSizeRel\OUTPUT_NAME_MINSIZEREL"
 CM_MULTILINE_OPTIONS_MINSIZEREL
 
@@ -159,7 +159,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 /nologo /subsystem:console /debug /machine:I386 /IGNORE:4089
-# ADD 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:"EXECUTABLE_OUTPUT_PATHRelWithDebInfo\OUTPUT_NAME_RELWITHDEBINFO"
 CM_MULTILINE_OPTIONS_RELWITHDEBINFO
 
-- 
cgit v0.12