From f89739b5d020154e104884a9a4d3b0fdc13cde04 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Mon, 26 Apr 2010 17:08:22 -0400
Subject: [PATCH] Help old C++ compilers place vtable symbols

At least one old Sun compiler does not produce weak vtable symbols.  It
places the vtable symbol in the object file that contains the body of
the first virtual, non-inline, non-pure-virtual method of a class.  This
is no more than one object file so a non-weak vtable symbol is okay.

However, when no such method exists the compiler puts the vtable in many
object files.  If the vtable symbol is not weak then the linker failes
with multiply-defined sybmol errors.  We work around this problem by
providing at least one method of this type in every class.

See issue #10543.
---
 Source/CMakeLists.txt                          |   11 +++++++++++
 Source/CTest/cmCTestCommand.cxx                |   16 ++++++++++++++++
 Source/CTest/cmCTestCommand.h                  |    1 +
 Source/CursesDialog/cmCursesFilePathWidget.cxx |    3 +++
 Source/CursesDialog/cmCursesFilePathWidget.h   |    1 +
 Source/cmCommand.cxx                           |   16 ++++++++++++++++
 Source/cmCommand.h                             |    2 +-
 Source/cmCommandArgumentsHelper.cxx            |    4 ++++
 Source/cmCommandArgumentsHelper.h              |    2 +-
 Source/cmCoreTryCompile.cxx                    |    4 ++++
 Source/cmCoreTryCompile.h                      |    2 +-
 Source/cmExecutionStatus.cxx                   |   16 ++++++++++++++++
 Source/cmExecutionStatus.h                     |    1 +
 Source/cmExportFileGenerator.cxx               |    5 +++++
 Source/cmExportFileGenerator.h                 |    2 +-
 Source/cmExternalMakefileProjectGenerator.cxx  |    4 ++++
 Source/cmExternalMakefileProjectGenerator.h    |    2 +-
 Source/cmFindFileCommand.cxx                   |    4 ++++
 Source/cmFindFileCommand.h                     |    1 +
 Source/cmFunctionBlocker.cxx                   |   16 ++++++++++++++++
 Source/cmFunctionBlocker.h                     |    2 +-
 Source/cmIStringStream.cxx                     |   16 ++++++++++++++++
 Source/cmOStringStream.cxx                     |   16 ++++++++++++++++
 Source/cmObject.cxx                            |   16 ++++++++++++++++
 Source/cmObject.h                              |    2 +-
 Source/cmStandardIncludes.h                    |    2 ++
 bootstrap                                      |    6 ++++++
 27 files changed, 166 insertions(+), 7 deletions(-)
 create mode 100644 Source/CTest/cmCTestCommand.cxx
 create mode 100644 Source/cmCommand.cxx
 create mode 100644 Source/cmExecutionStatus.cxx
 create mode 100644 Source/cmFunctionBlocker.cxx
 create mode 100644 Source/cmIStringStream.cxx
 create mode 100644 Source/cmOStringStream.cxx
 create mode 100644 Source/cmObject.cxx

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 49cbda7..eb02281 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -114,6 +114,8 @@ SET(SRCS
   cmBootstrapCommands.cxx
   cmCacheManager.cxx
   cmCacheManager.h
+  cmCommand.cxx
+  cmCommand.h
   cmCommands.cxx
   cmCommands.h
   cmCommandArgumentLexer.cxx
@@ -158,6 +160,8 @@ SET(SRCS
   cmDynamicLoader.cxx
   cmDynamicLoader.h
   ${ELF_SRCS}
+  cmExecutionStatus.cxx
+  cmExecutionStatus.h
   cmExprLexer.cxx
   cmExprParser.cxx
   cmExprParserHelper.cxx
@@ -173,6 +177,8 @@ SET(SRCS
   cmExtraEclipseCDT4Generator.h
   cmFileTimeComparison.cxx
   cmFileTimeComparison.h
+  cmFunctionBlocker.cxx
+  cmFunctionBlocker.h
   cmGeneratedFileStream.cxx
   cmGeneratorExpression.cxx
   cmGeneratorExpression.h
@@ -181,6 +187,7 @@ SET(SRCS
   cmGlobalUnixMakefileGenerator3.cxx
   cmGlobalUnixMakefileGenerator3.h
   cmGraphAdjacencyList.h
+  cmIStringStream.cxx
   cmInstallGenerator.h
   cmInstallGenerator.cxx
   cmInstallExportGenerator.cxx
@@ -206,6 +213,9 @@ SET(SRCS
   cmMakefileExecutableTargetGenerator.cxx
   cmMakefileLibraryTargetGenerator.cxx
   cmMakefileUtilityTargetGenerator.cxx
+  cmOStringStream.cxx
+  cmObject.cxx
+  cmObject.h
   cmOrderDirectories.cxx
   cmOrderDirectories.h
   cmPolicies.h
@@ -362,6 +372,7 @@ SET(CTEST_SRCS cmCTest.cxx
   CTest/cmCTestBuildAndTestHandler.cxx
   CTest/cmCTestBuildCommand.cxx
   CTest/cmCTestBuildHandler.cxx
+  CTest/cmCTestCommand.cxx
   CTest/cmCTestConfigureCommand.cxx
   CTest/cmCTestConfigureHandler.cxx
   CTest/cmCTestCoverageCommand.cxx
diff --git a/Source/CTest/cmCTestCommand.cxx b/Source/CTest/cmCTestCommand.cxx
new file mode 100644
index 0000000..7e8d64d
--- /dev/null
+++ b/Source/CTest/cmCTestCommand.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmCTestCommand.h"
+
+cmCTestCommand::~cmCTestCommand()
+{
+}
diff --git a/Source/CTest/cmCTestCommand.h b/Source/CTest/cmCTestCommand.h
index e2ebba8..d0387e6 100644
--- a/Source/CTest/cmCTestCommand.h
+++ b/Source/CTest/cmCTestCommand.h
@@ -29,6 +29,7 @@ class cmCTestCommand : public cmCommand
 public:
 
   cmCTestCommand() {this->CTest = 0; this->CTestScriptHandler = 0;}
+  virtual ~cmCTestCommand();
 
   cmCTest *CTest;
   cmCTestScriptHandler *CTestScriptHandler;
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.cxx b/Source/CursesDialog/cmCursesFilePathWidget.cxx
index 13bbcc9..c9e4d6a 100644
--- a/Source/CursesDialog/cmCursesFilePathWidget.cxx
+++ b/Source/CursesDialog/cmCursesFilePathWidget.cxx
@@ -18,3 +18,6 @@ cmCursesFilePathWidget::cmCursesFilePathWidget(int width, int height,
   this->Type = cmCacheManager::FILEPATH;
 }
 
+cmCursesFilePathWidget::~cmCursesFilePathWidget()
+{
+}
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.h b/Source/CursesDialog/cmCursesFilePathWidget.h
index 9d2972e..aeebf22 100644
--- a/Source/CursesDialog/cmCursesFilePathWidget.h
+++ b/Source/CursesDialog/cmCursesFilePathWidget.h
@@ -18,6 +18,7 @@ class cmCursesFilePathWidget : public cmCursesPathWidget
 {
 public:
   cmCursesFilePathWidget(int width, int height, int left, int top);
+  virtual ~cmCursesFilePathWidget();
 
 protected:
   cmCursesFilePathWidget(const cmCursesFilePathWidget& from);
diff --git a/Source/cmCommand.cxx b/Source/cmCommand.cxx
new file mode 100644
index 0000000..047afeb
--- /dev/null
+++ b/Source/cmCommand.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmCommand.h"
+
+cmCommand::~cmCommand()
+{
+}
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index 7817eb3..90bd49c 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -41,7 +41,7 @@ public:
   /**
    * Need virtual destructor to destroy real command type.
    */
-  virtual ~cmCommand() {}
+  virtual ~cmCommand();
   
   /**
    * Specify the makefile.
diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx
index 1c906a6..79b7c02 100644
--- a/Source/cmCommandArgumentsHelper.cxx
+++ b/Source/cmCommandArgumentsHelper.cxx
@@ -12,6 +12,10 @@
 
 #include "cmCommandArgumentsHelper.h"
 
+cmCommandArgument::~cmCommandArgument()
+{
+}
+
 cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args, 
                                      const char* key, 
                                      cmCommandArgumentGroup* group)
diff --git a/Source/cmCommandArgumentsHelper.h b/Source/cmCommandArgumentsHelper.h
index cb33ccd..5cef295 100644
--- a/Source/cmCommandArgumentsHelper.h
+++ b/Source/cmCommandArgumentsHelper.h
@@ -45,7 +45,7 @@ class cmCommandArgument
     cmCommandArgument(cmCommandArgumentsHelper* args, 
                       const char* key, 
                       cmCommandArgumentGroup* group=0);
-    virtual ~cmCommandArgument() {}
+    virtual ~cmCommandArgument();
 
     /// this argument may follow after arg. 0 means it comes first.
     void Follows(const cmCommandArgument* arg);
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index dab0c0d..21964a7 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -15,6 +15,10 @@
 #include "cmGlobalGenerator.h"
 #include <cmsys/Directory.hxx>
 
+cmCoreTryCompile::~cmCoreTryCompile()
+{
+}
+
 int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
 {
   this->BinaryDirectory = argv[1].c_str();
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index e29dde8..8b2cb35 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -23,7 +23,7 @@
 class cmCoreTryCompile : public cmCommand
 {
 public:
-
+  virtual ~cmCoreTryCompile();
   protected:
   /**
    * This is the core code for try compile. It is here so that other
diff --git a/Source/cmExecutionStatus.cxx b/Source/cmExecutionStatus.cxx
new file mode 100644
index 0000000..34e6e80
--- /dev/null
+++ b/Source/cmExecutionStatus.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmExecutionStatus.h"
+
+cmExecutionStatus::~cmExecutionStatus()
+{
+}
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index 9fbecac..3802e4e 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -25,6 +25,7 @@ public:
   cmTypeMacro(cmExecutionStatus, cmObject);
   
   cmExecutionStatus() { this->Clear();};
+  virtual ~cmExecutionStatus();
   
   virtual void SetReturnInvoked(bool val) 
   { this->ReturnInvoked = val; }
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index e2a6035..f0c7741 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -26,6 +26,11 @@ cmExportFileGenerator::cmExportFileGenerator()
 }
 
 //----------------------------------------------------------------------------
+cmExportFileGenerator::~cmExportFileGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
 void cmExportFileGenerator::AddConfiguration(const char* config)
 {
   this->Configurations.push_back(config);
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 05f73a2..6fb9b8c 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -26,7 +26,7 @@ class cmExportFileGenerator
 {
 public:
   cmExportFileGenerator();
-  virtual ~cmExportFileGenerator() {}
+  virtual ~cmExportFileGenerator();
 
   /** Set the full path to the export file to generate.  */
   void SetExportFile(const char* mainFile);
diff --git a/Source/cmExternalMakefileProjectGenerator.cxx b/Source/cmExternalMakefileProjectGenerator.cxx
index 6ed84bd..153c508 100644
--- a/Source/cmExternalMakefileProjectGenerator.cxx
+++ b/Source/cmExternalMakefileProjectGenerator.cxx
@@ -13,6 +13,10 @@
 
 #include "cmExternalMakefileProjectGenerator.h"
 
+cmExternalMakefileProjectGenerator::~cmExternalMakefileProjectGenerator()
+{
+}
+
 std::string cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
                                                    const char* globalGenerator,
                                                    const char* extraGenerator)
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index 46f1d31..285ab49 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -34,7 +34,7 @@ class cmExternalMakefileProjectGenerator
 {
 public:
 
-  virtual ~cmExternalMakefileProjectGenerator() {}
+  virtual ~cmExternalMakefileProjectGenerator();
 
   ///! Get the name for this generator.
   virtual const char* GetName() const = 0;
diff --git a/Source/cmFindFileCommand.cxx b/Source/cmFindFileCommand.cxx
index 897b4bb..e8c292c 100644
--- a/Source/cmFindFileCommand.cxx
+++ b/Source/cmFindFileCommand.cxx
@@ -23,3 +23,7 @@ cmFindFileCommand::cmFindFileCommand()
   cmSystemTools::ReplaceString(this->GenericDocumentation,
                                 "file in a directory", "full path to a file");
 }
+
+cmFindFileCommand::~cmFindFileCommand()
+{
+}
diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h
index aa0d25e..0b157e5 100644
--- a/Source/cmFindFileCommand.h
+++ b/Source/cmFindFileCommand.h
@@ -26,6 +26,7 @@ class cmFindFileCommand : public cmFindPathCommand
 {
 public:
   cmFindFileCommand();
+  virtual ~cmFindFileCommand();
   /**
    * This is a virtual constructor for the command.
    */
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
new file mode 100644
index 0000000..609368c
--- /dev/null
+++ b/Source/cmFunctionBlocker.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmFunctionBlocker.h"
+
+cmFunctionBlocker::~cmFunctionBlocker()
+{
+}
diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h
index c3b29e1..fe0346a 100644
--- a/Source/cmFunctionBlocker.h
+++ b/Source/cmFunctionBlocker.h
@@ -39,7 +39,7 @@ public:
   virtual bool ShouldRemove(const cmListFileFunction&,
                             cmMakefile&) {return false;}
 
-  virtual ~cmFunctionBlocker() {}
+  virtual ~cmFunctionBlocker();
 
   /** Set/Get the context in which this blocker is created.  */
   void SetStartingContext(cmListFileContext const& lfc)
diff --git a/Source/cmIStringStream.cxx b/Source/cmIStringStream.cxx
new file mode 100644
index 0000000..5ab4e77
--- /dev/null
+++ b/Source/cmIStringStream.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmStandardIncludes.h"
+
+cmIStringStream::~cmIStringStream()
+{
+}
diff --git a/Source/cmOStringStream.cxx b/Source/cmOStringStream.cxx
new file mode 100644
index 0000000..b9e9c1a
--- /dev/null
+++ b/Source/cmOStringStream.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmStandardIncludes.h"
+
+cmOStringStream::~cmOStringStream()
+{
+}
diff --git a/Source/cmObject.cxx b/Source/cmObject.cxx
new file mode 100644
index 0000000..36d9ae5
--- /dev/null
+++ b/Source/cmObject.cxx
@@ -0,0 +1,16 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmObject.h"
+
+cmObject::~cmObject()
+{
+}
diff --git a/Source/cmObject.h b/Source/cmObject.h
index 1a39aa7..76ac8ad 100644
--- a/Source/cmObject.h
+++ b/Source/cmObject.h
@@ -26,7 +26,7 @@ public:
   /**
    * Need virtual destructor to destroy real command type.
    */
-  virtual ~cmObject() {}
+  virtual ~cmObject();
   
   /**
    * The class name of the command.
diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h
index 5db0200..039e4f1 100644
--- a/Source/cmStandardIncludes.h
+++ b/Source/cmStandardIncludes.h
@@ -241,6 +241,7 @@ class cmOStringStream: public std::ostringstream
 {
 public:
   cmOStringStream() {}
+  virtual ~cmOStringStream();
 private:
   cmOStringStream(const cmOStringStream&);
   void operator=(const cmOStringStream&);
@@ -251,6 +252,7 @@ public:
   typedef std::istringstream Superclass;
   cmIStringStream() {}
   cmIStringStream(const std::string& s): Superclass(s) {}
+  virtual ~cmIStringStream();
 private:
   cmIStringStream(const cmIStringStream&);
   void operator=(const cmIStringStream&);
diff --git a/bootstrap b/bootstrap
index bcd11a5..2963c4e 100755
--- a/bootstrap
+++ b/bootstrap
@@ -167,6 +167,7 @@ CMAKE_CXX_SOURCES="\
   cmCommandArgumentLexer \
   cmCommandArgumentParser \
   cmCommandArgumentParserHelper \
+  cmCommand \
   cmDefinitions \
   cmDepends \
   cmDependsC \
@@ -179,6 +180,7 @@ CMAKE_CXX_SOURCES="\
   cmPropertyDefinitionMap \
   cmMakeDepend \
   cmMakefile \
+  cmExecutionStatus \
   cmExportFileGenerator \
   cmExportInstallFileGenerator \
   cmInstallDirectoryGenerator \
@@ -220,6 +222,10 @@ CMAKE_CXX_SOURCES="\
   cmExprLexer \
   cmExprParser \
   cmExprParserHelper \
+  cmOStringStream \
+  cmIStringStream \
+  cmFunctionBlocker \
+  cmObject \
 "
 
 if ${cmake_system_mingw}; then
-- 
1.7.0

