[Cmake-commits] CMake branch, next, updated. v3.3.0-rc3-705-g24fad5b

Brad King brad.king at kitware.com
Fri Jun 26 14:37:04 EDT 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  24fad5b0f0ddd90bd6fd6c47e263527e99299dd3 (commit)
       via  16853cc3dc6fd428658f2a976fadfbbc82ab7af6 (commit)
       via  11911857ed48cbd5e1c71a8c646e90e033cca99a (commit)
       via  12378c07b22829b19e1c7ef47a3cda4f213164ba (commit)
       via  bee7a4441c7d2a65041eeaee63131ea610c6ecc4 (commit)
       via  e86309701d5d613a74fc8153c67a142c449c1d37 (commit)
       via  3ef9d2461099cbfa69689df2ad84aefcbf38e34a (commit)
      from  0a129deab731bd65c60ef5bd45f1c865de601e78 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=24fad5b0f0ddd90bd6fd6c47e263527e99299dd3
commit 24fad5b0f0ddd90bd6fd6c47e263527e99299dd3
Merge: 0a129de 16853cc
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Jun 26 14:37:03 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Fri Jun 26 14:37:03 2015 -0400

    Merge topic 'auto_export_dll_symbols' into next
    
    16853cc3 Windows: Optionally generate DLL module definition files automatically
    11911857 bindexplib: Build source as part of CMakeLib
    12378c07 bindexplib: Wrap long lines
    bee7a444 bindexplib: Drop code that CMake does not need
    e8630970 bindexplib: Add copyright/license notice block
    3ef9d246 bindexplib: Import original implementation from CERN


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=16853cc3dc6fd428658f2a976fadfbbc82ab7af6
commit 16853cc3dc6fd428658f2a976fadfbbc82ab7af6
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Jun 26 14:33:11 2015 -0400

    Windows: Optionally generate DLL module definition files automatically
    
    Create target property WINDOWS_EXPORT_ALL_SYMBOLS to automatically
    generate a module definition file from MS-compatible .obj files and give
    it to the linker in order to export all symbols from the .dll part of a
    SHARED library.

diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 9a60a10..b767ed6 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -251,6 +251,7 @@ Properties on Targets
    /prop_tgt/VS_WINRT_EXTENSIONS
    /prop_tgt/VS_WINRT_REFERENCES
    /prop_tgt/WIN32_EXECUTABLE
+   /prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
    /prop_tgt/XCODE_ATTRIBUTE_an-attribute
    /prop_tgt/XCTEST
 
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 0e6222f..7c7db5e 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -275,6 +275,7 @@ Variables that Control the Build
    /variable/CMAKE_USE_RELATIVE_PATHS
    /variable/CMAKE_VISIBILITY_INLINES_HIDDEN
    /variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
+   /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
    /variable/CMAKE_WIN32_EXECUTABLE
    /variable/CMAKE_XCODE_ATTRIBUTE_an-attribute
    /variable/EXECUTABLE_OUTPUT_PATH
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..3f48af8
--- /dev/null
+++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,18 @@
+WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------
+
+This property is implemented only for MS-compatible tools on Windows.
+
+Enable this boolean property to automatically create a module definition
+(``.def``) file with all global symbols found in the input ``.obj`` files
+for a ``SHARED`` library on Windows.  The module definition file will be
+passed to the linker causing all symbols to be exported from the ``.dll``.
+For global *data* symbols, ``__declspec(dllimport)`` must still be used when
+compiling against the code in the ``.dll``.  All other function symbols will
+be automatically exported and imported by callers.  This simplifies porting
+projects to Windows by reducing the need for explicit ``dllexport`` markup,
+even in ``C++`` classes.
+
+This property is initialized by the value of
+the :variable:`CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` variable if it is set
+when a target is created.
diff --git a/Help/release/dev/auto_export_dll_symbols.rst b/Help/release/dev/auto_export_dll_symbols.rst
new file mode 100644
index 0000000..9db2b5e
--- /dev/null
+++ b/Help/release/dev/auto_export_dll_symbols.rst
@@ -0,0 +1,6 @@
+auto_export_dll_symbols
+-----------------------
+
+* On Windows with MS-compatible tools, CMake learned to optionally
+  generate a module definition (``.def``) file for ``SHARED`` libraries.
+  See the :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
diff --git a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..1636842
--- /dev/null
+++ b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,6 @@
+CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------------
+
+Default value for :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
+This variable is used to initialize the property on each target as it is
+created.
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 13fe8bc..aeaa2bd 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -46,8 +46,10 @@ else()
   set(_PLATFORM_LINK_FLAGS "")
 endif()
 
+set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
 if(CMAKE_GENERATOR MATCHES "Visual Studio 6")
    set (CMAKE_NO_BUILD_TYPE 1)
+   set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 0) # not implemented for VS6
 endif()
 if(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
   set (CMAKE_NO_BUILD_TYPE 1)
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 0de0ddf..0dd9f75 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -217,7 +217,16 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                symbol = stringTable + pSymbolTable->N.Name.Long;
             }
 
+            // clear out any leading spaces
             while (isspace(symbol[0])) symbol.erase(0,1);
+            // if it starts with _ and has an @ then it is a __cdecl
+            // so remove the @ stuff for the export
+            if(symbol[0] == '_') {
+               std::string::size_type posAt = symbol.find('@');
+               if (posAt != std::string::npos) {
+                  symbol.erase(posAt);
+               }
+            }
             if (symbol[0] == '_') symbol.erase(0,1);
             if (fImportFlag) {
                fImportFlag = 0;
@@ -229,9 +238,13 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
             */
             const char *scalarPrefix = "??_G";
             const char *vectorPrefix = "??_E";
+            // original code had a check for
+            // symbol.find("real@") == std::string::npos)
+            // but if this disallows memmber functions with the name real
+            // if scalarPrefix and vectorPrefix are not found then print
+            // the symbol
             if (symbol.compare(0, 4, scalarPrefix) &&
-               symbol.compare(0, 4, vectorPrefix) &&
-               symbol.find("real@") == std::string::npos)
+                symbol.compare(0, 4, vectorPrefix) )
             {
                SectChar =
                 pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
@@ -243,7 +256,7 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                        !(SectChar & IMAGE_SCN_MEM_READ)) {
                      fprintf(fout, "\t%s\n", symbol.c_str());
                   } else {
-                     //                    printf(" strange symbol: %s \n",s);
+                     // printf(" strange symbol: %s \n",symbol.c_str());
                   }
                }
             }
@@ -328,7 +341,7 @@ DumpFile(const char* filename, FILE *fout)
       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 
    if (hFile == INVALID_HANDLE_VALUE) {
-      fprintf(stderr, "Couldn't open file with CreateFile()\n");
+      fprintf(stderr, "Couldn't open file [%s] with CreateFile()\n", filename);
       return;
    }
 
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 585d19a..61cec6c 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -887,3 +887,64 @@ std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir(
     }
   return tmp;
 }
+
+void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
+  cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands,
+  std::string const& configName)
+{
+  std::vector<std::string> outputs;
+  std::string deffile = "$(IntDir)/exportall.def";
+  outputs.push_back(deffile);
+  std::vector<std::string> empty;
+  std::vector<cmSourceFile const*> objectSources;
+  gt->GetObjectSources(objectSources, configName);
+  std::map<cmSourceFile const*, std::string> mapping;
+  for(std::vector<cmSourceFile const*>::const_iterator it
+        = objectSources.begin(); it != objectSources.end(); ++it)
+    {
+    mapping[*it];
+    }
+  gt->LocalGenerator->
+    ComputeObjectFilenames(mapping, gt);
+  std::string obj_dir = gt->ObjectDirectory;
+  std::string cmakeCommand = cmSystemTools::GetCMakeCommand();
+  cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand);
+  cmCustomCommandLine cmdl;
+  cmdl.push_back(cmakeCommand);
+  cmdl.push_back("-E");
+  cmdl.push_back("__create_def");
+  cmdl.push_back(deffile);
+  std::string objs_file = gt->Target->GetName();
+  objs_file += ".dir/" + configName;
+  cmSystemTools::MakeDirectory(objs_file.c_str());
+  objs_file += "/exportall.def.objs";
+  cmdl.push_back(objs_file);
+  std::ofstream fout(objs_file.c_str());
+  if(!fout)
+    {
+    cmSystemTools::Error("could not open ", objs_file.c_str());
+    return;
+    }
+  for(std::vector<cmSourceFile const*>::const_iterator it
+        = objectSources.begin(); it != objectSources.end(); ++it)
+    {
+    // Find the object file name corresponding to this source file.
+    std::map<cmSourceFile const*, std::string>::const_iterator
+      map_it = mapping.find(*it);
+    // It must exist because we populated the mapping just above.
+    assert(!map_it->second.empty());
+    std::string objFile = obj_dir + map_it->second;
+    // replace $(ConfigurationName) in the object names
+    cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
+                                 configName.c_str());
+    fout << objFile << "\n";
+    }
+  cmCustomCommandLines commandLines;
+  commandLines.push_back(cmdl);
+  cmCustomCommand command(gt->Target->GetMakefile(),
+                          outputs, empty, empty,
+                          commandLines,
+                          "Auto build dll exports",
+                          ".");
+  commands.push_back(command);
+}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 69b4564..022e190 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -102,6 +102,10 @@ public:
                                       const std::string& config) const;
 
   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+  void AddSymbolExportCommand(
+    cmGeneratorTarget*, std::vector<cmCustomCommand>& commands,
+    std::string const& configName);
 protected:
   virtual void Generate();
 
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index dc3a16d..e4eb014 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1081,6 +1081,16 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL);
     linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
     }
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    std::string const autodef_prop = "WINDOWS_EXPORT_ALL_SYMBOLS";
+    const char *autodef = target.GetProperty(autodef_prop);
+    if (autodef && *autodef)
+      {
+      linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
+      }
+    }
   switch(target.GetType())
     {
     case cmTarget::UNKNOWN_LIBRARY:
@@ -2015,7 +2025,30 @@ void cmLocalVisualStudio7Generator
   // Add pre-link event.
   tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
   event.Start(tool);
-  event.Write(target.GetPreLinkCommands());
+  bool addedPrelink = false;
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    std::string const autodef_prop = "WINDOWS_EXPORT_ALL_SYMBOLS";
+    const char *autodef = target.GetProperty(autodef_prop);
+    if (autodef && *autodef)
+      {
+      addedPrelink = true;
+      std::vector<cmCustomCommand> commands =
+        target.GetPreLinkCommands();
+      cmGlobalVisualStudioGenerator* gg
+        = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+      cmGeneratorTarget* gt =
+        this->GlobalGenerator->GetGeneratorTarget(&target);
+      gg->AddSymbolExportCommand(
+        gt, commands, configName);
+      event.Write(commands);
+      }
+    }
+  if (!addedPrelink)
+    {
+    event.Write(target.GetPreLinkCommands());
+    }
   cmsys::auto_ptr<cmCustomCommand> pcc(
     this->MaybeCreateImplibDir(target, configName, this->FortranProject));
   if(pcc.get())
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 660027c..f807517 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -563,6 +563,57 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
                           useResponseFileForObjects, buildObjs, depends,
                           useWatcomQuote);
 
+  // maybe create .def file from list of objects
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    std::string const autodef_prop = "WINDOWS_EXPORT_ALL_SYMBOLS";
+    const char *autodef = this->Target->GetProperty(autodef_prop);
+    if (autodef && *autodef)
+      {
+      std::string name_of_def_file =
+        this->Target->GetSupportDirectory();
+      name_of_def_file += std::string("/") +
+        this->Target->GetName();
+      name_of_def_file += ".def";
+      std::string cmd = cmSystemTools::GetCMakeCommand();
+      cmd = this->Convert(cmd, cmLocalGenerator::NONE,
+                          cmLocalGenerator::SHELL);
+      cmd += " -E __create_def ";
+      cmd += this->Convert(name_of_def_file,
+                           cmLocalGenerator::START_OUTPUT,
+                           cmLocalGenerator::SHELL);
+      cmd += " ";
+      std::string objlist_file = name_of_def_file;
+      objlist_file += ".objs";
+      cmd += this->Convert(objlist_file,
+                           cmLocalGenerator::START_OUTPUT,
+                           cmLocalGenerator::SHELL);
+      real_link_commands.push_back(cmd);
+      // create a list of obj files for the -E __create_def to read
+      std::ofstream fout(objlist_file.c_str());
+      for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+          i != this->Objects.end(); ++i)
+        {
+        fout << *i << "\n";
+        }
+      for(std::vector<std::string>::const_iterator i =
+        this->ExternalObjects.begin();
+          i != this->ExternalObjects.end(); ++i)
+        {
+        fout << *i << "\n";
+        }
+      // now add the def file link flag
+      linkFlags += " ";
+      linkFlags +=
+        this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+      linkFlags += this->Convert(name_of_def_file,
+                                 cmLocalGenerator::START_OUTPUT,
+                                 cmLocalGenerator::SHELL);
+      linkFlags += " ";
+      }
+    }
+
   cmLocalGenerator::RuleVariables vars;
   vars.TargetPDB = targetOutPathPDB.c_str();
 
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 2fe53bf..4df0993 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -486,6 +486,24 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                           linkPath,
                           &genTarget,
                           useWatcomQuote);
+  if(this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")
+     && target.GetType() == cmTarget::SHARED_LIBRARY)
+    {
+    std::string const autodef_prop = "WINDOWS_EXPORT_ALL_SYMBOLS";
+    const char *autodef = target.GetProperty(autodef_prop);
+    if (autodef && *autodef)
+      {
+      std::string dllname = targetOutput;
+      std::string name_of_def_file
+        = target.GetSupportDirectory();
+      name_of_def_file += "/" + target.GetName();
+      name_of_def_file += ".def ";
+      vars["LINK_FLAGS"] += " /DEF:";
+      vars["LINK_FLAGS"] += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(name_of_def_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      }
+    }
 
   this->addPoolNinjaVariable("JOB_POOL_LINK", &target, vars);
 
@@ -600,6 +618,43 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
       }
     }
 
+  // maybe create .def file from list of objects
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    std::string const autodef_prop = "WINDOWS_EXPORT_ALL_SYMBOLS";
+    const char *autodef = target.GetProperty(autodef_prop);
+    if (autodef && *autodef)
+      {
+      std::string cmakeCommand =
+      this->GetLocalGenerator()->ConvertToOutputFormat(
+        cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+      std::string dllname = targetOutput;
+      std::string name_of_def_file
+        = target.GetSupportDirectory();
+      name_of_def_file += "/" + target.GetName();
+      name_of_def_file += ".def";
+      std::string cmd = cmakeCommand;
+      cmd += " -E __create_def ";
+      cmd += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(name_of_def_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      cmd += " ";
+      cmNinjaDeps objs = this->GetObjects();
+      std::string obj_list_file = name_of_def_file;
+      obj_list_file += ".objs";
+      cmd += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(obj_list_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      preLinkCmdLines.push_back(cmd);
+      // create a list of obj files for the -E __create_def to read
+      std::ofstream fout(obj_list_file.c_str());
+      for(cmNinjaDeps::iterator i=objs.begin(); i != objs.end(); ++i)
+        {
+        fout << *i << "\n";
+        }
+      }
+    }
   // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
   // the link commands.
   if (!preLinkCmdLines.empty())
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index c7a13bc..8448431 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -429,6 +429,11 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     {
     this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
     }
+  if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY)
+    {
+    this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", 0);
+    }
+
   if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
     {
     this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 12a1e42..03acf2f 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2466,6 +2466,17 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
                            "%(IgnoreSpecificDefaultLibraries)");
     }
 
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    std::string const autodef_prop = "WINDOWS_EXPORT_ALL_SYMBOLS";
+    const char *autodef = this->Target->GetProperty(autodef_prop);
+    if (autodef && *autodef)
+      {
+      linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
+      }
+    }
+
   this->LinkOptions[config] = pOptions.release();
   return true;
 }
@@ -2613,8 +2624,27 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
 void
 cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName)
 {
-  this->WriteEvent("PreLinkEvent",
-                   this->Target->GetPreLinkCommands(), configName);
+  bool addedPrelink = false;
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    std::string const autodef_prop = "WINDOWS_EXPORT_ALL_SYMBOLS";
+    const char *autodef = this->Target->GetProperty(autodef_prop);
+    if (autodef && *autodef)
+      {
+      addedPrelink = true;
+      std::vector<cmCustomCommand> commands =
+        this->Target->GetPreLinkCommands();
+      this->GlobalGenerator->AddSymbolExportCommand(
+        this->GeneratorTarget, commands, configName);
+      this->WriteEvent("PreLinkEvent", commands, configName);
+      }
+    }
+  if (!addedPrelink)
+    {
+    this->WriteEvent("PreLinkEvent",
+                     this->Target->GetPreLinkCommands(), configName);
+    }
   this->WriteEvent("PreBuildEvent",
                    this->Target->GetPreBuildCommands(), configName);
   this->WriteEvent("PostBuildEvent",
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 3ea2186..d97abcc 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -34,6 +34,10 @@
 #include <time.h>
 
 #include <stdlib.h> // required for atoi
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+// defined in binexplib.cxx
+void DumpFile(const char* filename, FILE *fout);
+#endif
 
 void CMakeCommandUsage(const char* program)
 {
@@ -211,6 +215,38 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
       return 0;
       }
 
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+    else if(args[1] == "__create_def")
+      {
+      if(args.size() < 4)
+        {
+        std::cerr <<
+          "__create_def Usage: -E __create_def outfile.def objlistfile\n";
+        return 1;
+        }
+      FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+      if(!fout)
+        {
+        std::cerr << "could not open output .def file: " << args[2].c_str()
+                  << "\n";
+        return 1;
+        }
+      cmsys::ifstream fin(args[3].c_str(),
+                          std::ios::in | std::ios::binary);
+      if(!fin)
+        {
+        std::cerr << "could not open object list file: " << args[3].c_str()
+                  << "\n";
+        return 1;
+        }
+      std::string objfile;
+      while(cmSystemTools::GetLineFromStream(fin, objfile))
+        {
+        DumpFile(objfile.c_str(), fout);
+        }
+      return 0;
+      }
+#endif
     // run include what you use command and then run the compile
     // command. This is an internal undocumented option and should
     // only be used by CMake itself when running iwyu.
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
new file mode 100644
index 0000000..c426f66
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -0,0 +1,5 @@
+project(autoexport)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
+add_library(autoexport SHARED hello.cxx world.cxx foo.c)
+add_executable(say say.cxx)
+target_link_libraries(say autoexport)
diff --git a/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
new file mode 100644
index 0000000..d483c2c
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
@@ -0,0 +1 @@
+^.*$
diff --git a/Tests/RunCMake/AutoExportDll/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
new file mode 100644
index 0000000..18dfd26
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
new file mode 100644
index 0000000..f4e08ec
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+set(RunCMake_TEST_NO_CLEAN TRUE)
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AutoExport-build")
+# start by cleaning up because we don't clean up along the way
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+# configure the AutoExport test
+run_cmake(AutoExport)
+unset(RunCMake_TEST_OPTIONS)
+# don't run this test on VS 6 as it is not supported
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 6|Watcom WMake|Borland Makefiles")
+  return()
+endif()
+# we build debug so the say.exe will be found in Debug/say.exe for
+# Visual Studio generators
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
+  set(INTDIR "Debug/")
+endif()
+# build AutoExport
+run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build
+  ${RunCMake_TEST_BINARY_DIR} --config Debug)
+# run the executable that uses symbols from the dll
+if(WIN32)
+  set(EXE_EXT ".exe")
+endif()
+run_cmake_command(AutoExportRun
+  ${RunCMake_BINARY_DIR}/AutoExport-build/${INTDIR}say${EXE_EXT})
diff --git a/Tests/RunCMake/AutoExportDll/foo.c b/Tests/RunCMake/AutoExportDll/foo.c
new file mode 100644
index 0000000..4b1318b
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/foo.c
@@ -0,0 +1,15 @@
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+int WINAPI foo()
+{
+  return 10;
+}
+
+int bar()
+{
+  return 5;
+}
diff --git a/Tests/RunCMake/AutoExportDll/hello.cxx b/Tests/RunCMake/AutoExportDll/hello.cxx
new file mode 100644
index 0000000..ad83420
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.cxx
@@ -0,0 +1,13 @@
+#include <iostream>
+#include "hello.h"
+int Hello::Data = 0;
+void Hello::real()
+{
+  return;
+}
+void hello()
+{
+  std::cout << "hello";
+}
+void Hello::operator delete[](void*) {};
+void Hello::operator delete(void*) {};
diff --git a/Tests/RunCMake/AutoExportDll/hello.h b/Tests/RunCMake/AutoExportDll/hello.h
new file mode 100644
index 0000000..3749b97
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.h
@@ -0,0 +1,18 @@
+#ifndef _MSC_VER
+#define winexport
+#else
+#ifdef autoexport_EXPORTS
+#define winexport
+#else
+#define winexport __declspec(dllimport)
+#endif
+#endif
+
+class Hello
+{
+public:
+  static winexport int Data;
+  void real();
+  static void operator delete[](void*);
+  static void operator delete(void*);
+};
diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx
new file mode 100644
index 0000000..655b3c2
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/say.cxx
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "hello.h"
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+extern "C"
+{
+// test __cdecl stuff
+  int WINAPI foo();
+// test regular C
+  int bar();
+}
+
+// test c++ functions
+// forward declare hello and world
+void hello();
+void world();
+
+int main()
+{
+  // test static data (needs declspec to work)
+  Hello::Data = 120;
+  Hello h;
+  h.real();
+  hello();
+  printf(" ");
+  world();
+  printf("\n");
+  foo();
+  printf("\n");
+  bar();
+  printf("\n");
+  return 0;
+}
diff --git a/Tests/RunCMake/AutoExportDll/world.cxx b/Tests/RunCMake/AutoExportDll/world.cxx
new file mode 100644
index 0000000..8107949
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/world.cxx
@@ -0,0 +1,6 @@
+#include <iostream>
+
+void world()
+{
+  std::cout << "world";
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index bc706d3..743ef4b 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -266,3 +266,6 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
 endif()
 
 add_RunCMake_test_group(CPack "DEB;RPM")
+# add a test to make sure symbols are exported from a shared library
+# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
+add_RunCMake_test(AutoExportDll)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=11911857ed48cbd5e1c71a8c646e90e033cca99a
commit 11911857ed48cbd5e1c71a8c646e90e033cca99a
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Jun 26 14:08:52 2015 -0400

    bindexplib: Build source as part of CMakeLib

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 6d012fd..069f283 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -430,6 +430,7 @@ if (WIN32)
   set(SRCS ${SRCS}
     cmCallVisualStudioMacro.cxx
     cmCallVisualStudioMacro.h
+    bindexplib.cxx
     )
 
   if(NOT UNIX)
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index d523d22..0de0ddf 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -73,10 +73,12 @@
 
 static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
 
+#include <cmsys/Encoding.hxx>
 #include <windows.h>
 #include <stdio.h>
 #include <string>
 #include <fstream>
+#include <iostream>
 
 /*
 *  The names of the first group of possible symbol table storage classes
@@ -188,7 +190,7 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader,
 void
 DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                      PIMAGE_SECTION_HEADER pSectionHeaders,
-                     FILE *fout, unsigned cSymbols)
+                     FILE *fout, DWORD_PTR cSymbols)
 {
    unsigned i;
    PSTR stringTable;
@@ -314,14 +316,15 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
 *----------------------------------------------------------------------
 */
 void
-DumpFile(LPSTR filename, FILE *fout)
+DumpFile(const char* filename, FILE *fout)
 {
    HANDLE hFile;
    HANDLE hFileMapping;
    LPVOID lpFileBase;
    PIMAGE_DOS_HEADER dosHeader;
 
-   hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+   hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(),
+                       GENERIC_READ, FILE_SHARE_READ, NULL,
       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 
    if (hFile == INVALID_HANDLE_VALUE) {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=12378c07b22829b19e1c7ef47a3cda4f213164ba
commit 12378c07b22829b19e1c7ef47a3cda4f213164ba
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Jun 26 14:03:51 2015 -0400

    bindexplib: Wrap long lines

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 4a192c1..d523d22 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -128,7 +128,8 @@ const char* StrNStr(const char* start, const char* find, size_t &size) {
  *----------------------------------------------------------------------
  */
 int
-HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout)
+HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader,
+                    PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout)
 {
     static int fImportFlag = 0;  /*  The status is nor defined yet */
     WORD i;
@@ -143,12 +144,14 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER p
     i = 0;
     foundExports = 0;
     pDirectivesSectionHeader = 0;
-    for(i = 0; i < pImageFileHeader->NumberOfSections && !pDirectivesSectionHeader; i++)
+    for(i = 0; (i < pImageFileHeader->NumberOfSections &&
+                !pDirectivesSectionHeader); i++)
        if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
           pDirectivesSectionHeader = &pSectionHeaders[i];
    if (!pDirectivesSectionHeader) return 0;
 
-    rawdata=(const char*)pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
+    rawdata=(const char*)
+      pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
     if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
 
     size = pDirectivesSectionHeader->SizeOfRawData;
@@ -183,7 +186,8 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER p
 *----------------------------------------------------------------------
 */
 void
-DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
+DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
+                     PIMAGE_SECTION_HEADER pSectionHeaders,
                      FILE *fout, unsigned cSymbols)
 {
    unsigned i;
@@ -198,7 +202,8 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
    stringTable = (PSTR)&pSymbolTable[cSymbols];
 
    for ( i=0; i < cSymbols; i++ ) {
-      if (pSymbolTable->SectionNumber > 0 && ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+      if (pSymbolTable->SectionNumber > 0 &&
+          ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
          if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
             /*
             *    The name of the Function entry points
@@ -226,12 +231,14 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
                symbol.compare(0, 4, vectorPrefix) &&
                symbol.find("real@") == std::string::npos)
             {
-               SectChar = pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+               SectChar =
+                pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
                if (!pSymbolTable->Type  && (SectChar & IMAGE_SCN_MEM_WRITE)) {
                   // Read only (i.e. constants) must be excluded
                   fprintf(fout, "\t%s \t DATA\n", symbol.c_str());
                } else {
-                  if ( pSymbolTable->Type  || !(SectChar & IMAGE_SCN_MEM_READ)) {
+                  if ( pSymbolTable->Type  ||
+                       !(SectChar & IMAGE_SCN_MEM_READ)) {
                      fprintf(fout, "\t%s\n", symbol.c_str());
                   } else {
                      //                    printf(" strange symbol: %s \n",s);
@@ -240,7 +247,8 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
             }
          }
       }
-      else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && !pSymbolTable->Type && 0){
+      else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED &&
+               !pSymbolTable->Type && 0) {
          /*
          *    The IMPORT global variable entry points
          */
@@ -290,9 +298,11 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
       pImageFileHeader->SizeOfOptionalHeader);
 
 
-   int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
+   int haveExports = HaveExportedObjects(pImageFileHeader,
+                                         PCOFFSectionHeaders, fout);
    if (!haveExports)
-       DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
+       DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders,
+                            fout, COFFSymbolCount);
 }
 
 /*
@@ -341,7 +351,8 @@ DumpFile(LPSTR filename, FILE *fout)
    }
    /* Does it look like a i386 COFF OBJ file??? */
    else if (
-           ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) || (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+           ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) ||
+            (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
            && (dosHeader->e_sp == 0)
            ) {
       /*

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bee7a4441c7d2a65041eeaee63131ea610c6ecc4
commit bee7a4441c7d2a65041eeaee63131ea610c6ecc4
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Jun 26 14:03:43 2015 -0400

    bindexplib: Drop code that CMake does not need

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index a86318f..4a192c1 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -79,55 +79,6 @@ static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
 #include <fstream>
 
 /*
-*----------------------------------------------------------------------
-* GetArgcArgv --
-*
-*      Break up a line into argc argv
-*----------------------------------------------------------------------
-*/
-int
-GetArgcArgv(std::string &s, char **argv)
-{
-   int quote = 0;
-   int argc = 0;
-   std::string::iterator bp = s.begin();
-
-   while (1) {
-      while (isspace(*bp)) {
-         bp++;
-      }
-      if (*bp == '\n' || *bp == '\0') {
-         *bp = '\0';
-         return argc;
-      }
-      if (*bp == '\"') {
-         quote = 1;
-         bp++;
-      }
-      argv[argc++] = &(*bp);
-
-      while (*bp != '\0') {
-         if (quote) {
-            if (*bp == '\"') {
-               quote = 0;
-               *bp = '\0';
-               bp++;
-               break;
-            }
-            bp++;
-            continue;
-         }
-         if (isspace(*bp)) {
-            *bp = '\0';
-            bp++;
-            break;
-         }
-         bp++;
-      }
-   }
-}
-
-/*
 *  The names of the first group of possible symbol table storage classes
 */
 char * SzStorageClass1[] = {
@@ -145,216 +96,6 @@ char * SzStorageClass2[] = {
 };
 
 /*
-*----------------------------------------------------------------------
-* GetSZStorageClass --
-*
-*      Given a symbol storage class value, return a descriptive
-*      ASCII string
-*----------------------------------------------------------------------
-*/
-PSTR
-GetSZStorageClass(BYTE storageClass)
-{
-   if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
-      return SzStorageClass1[storageClass];
-   else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
-      && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
-      return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
-   else
-      return "???";
-}
-
-void AddHex(std::string& buf, long val, bool caps=false)
-{
-   buf += "0x";
-   size_t len=buf.length();
-   while (val) {
-      char hex = (char)(val & 16);
-      val = val >> 4;
-      if (hex<10) hex+='0';
-      else if (caps) hex+='A'-10;
-      else hex+='a'-10;
-      buf.insert(len, hex, 1);
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* GetSectionName --
-*
-*      Used by DumpSymbolTable, it gives meaningful names to
-*      the non-normal section number.
-*
-* Results:
-*      A name is returned in buffer
-*----------------------------------------------------------------------
-*/
-void
-GetSectionName(PIMAGE_SYMBOL pSymbolTable, std::string& buffer)
-{
-   DWORD section;
-
-   section = pSymbolTable->SectionNumber;
-
-   switch ( (SHORT)section )
-   {
-   case IMAGE_SYM_UNDEFINED: if (pSymbolTable->Value) buffer += "COMM"; else buffer += "UNDEF"; break;
-   case IMAGE_SYM_ABSOLUTE:  buffer += "ABS  "; break;
-   case IMAGE_SYM_DEBUG:     buffer += "DEBUG"; break;
-   default: AddHex(buffer, section, true);
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* GetSectionCharacteristics --
-*
-*      Converts the Characteristics field of IMAGE_SECTION_HEADER
-*      to print.
-*
-*  Results:
-*       A definiton of the section symbol type
-*----------------------------------------------------------------------
-*/
-void
-GetSectionCharacteristics(PIMAGE_SECTION_HEADER pSectionHeaders, int nSectNum, std::string &buffer)
-{
-   DWORD SectChar;
-   std::string TempBuf;
-   buffer.clear();
-   if (nSectNum > 0) {
-      SectChar = pSectionHeaders[nSectNum-1].Characteristics;
-
-      buffer = " ";
-      AddHex(buffer, SectChar);
-      if       (SectChar & IMAGE_SCN_CNT_CODE)                buffer += " Code";
-      else if  (SectChar & IMAGE_SCN_CNT_INITIALIZED_DATA)    buffer += " Init. data";
-      else if  (SectChar & IMAGE_SCN_CNT_UNINITIALIZED_DATA ) buffer += " UnInit data";
-      else                                                    buffer += " Unknow type";
-
-      if   (SectChar & IMAGE_SCN_MEM_READ)  {
-         buffer += " Read";
-         if (SectChar & IMAGE_SCN_MEM_WRITE)
-            buffer += " and Write";
-         else buffer += " only";
-      }
-      else if (SectChar & IMAGE_SCN_MEM_WRITE)
-         buffer +=" Write only";
-
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* DumpSymbolTable --
-*
-*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
-*      it to dump tables from OBJs.
-*----------------------------------------------------------------------
-*/
-void
-DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout, unsigned cSymbols)
-{
-   unsigned i;
-   PSTR stringTable;
-   std::string sectionName;
-   std::string sectionCharacter;
-   int iSectNum;
-
-   fprintf(fout, "Symbol Table - %X entries  (* = auxillary symbol)\n",
-      cSymbols);
-
-   fprintf(fout,
-      "Indx Name                 Value    Section    cAux  Type    Storage  Character\n"
-      "---- -------------------- -------- ---------- ----- ------- -------- ---------\n");
-
-   /*
-   * The string table apparently starts right after the symbol table
-   */
-   stringTable = (PSTR)&pSymbolTable[cSymbols];
-
-   for ( i=0; i < cSymbols; i++ ) {
-      fprintf(fout, "%04X ", i);
-      if ( pSymbolTable->N.Name.Short != 0 )
-         fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
-      else
-         fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
-
-      fprintf(fout, " %08X", pSymbolTable->Value);
-
-      iSectNum = pSymbolTable->SectionNumber;
-      GetSectionName(pSymbolTable, sectionName);
-      fprintf(fout, " sect:%s aux:%X type:%02X st:%s",
-         sectionName.c_str(),
-         pSymbolTable->NumberOfAuxSymbols,
-         pSymbolTable->Type,
-         GetSZStorageClass(pSymbolTable->StorageClass) );
-
-      GetSectionCharacteristics(pSectionHeaders,iSectNum,sectionCharacter);
-      fprintf(fout," hc: %s \n",sectionCharacter.c_str());
-#if 0
-      if ( pSymbolTable->NumberOfAuxSymbols )
-         DumpAuxSymbols(pSymbolTable);
-#endif
-
-      /*
-      * Take into account any aux symbols
-      */
-      i += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable++;
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* DumpExternals --
-*
-*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
-*      it to dump tables from OBJs.
-*----------------------------------------------------------------------
-*/
-void
-DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
-{
-   unsigned i;
-   PSTR stringTable;
-   std::string symbol;
-
-   /*
-   * The string table apparently starts right after the symbol table
-   */
-   stringTable = (PSTR)&pSymbolTable[cSymbols];
-
-   for ( i=0; i < cSymbols; i++ ) {
-      if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
-         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
-            if (pSymbolTable->N.Name.Short != 0) {
-               symbol = "";
-               symbol.insert(0, (const char *)(pSymbolTable->N.ShortName), 8);
-            } else {
-               symbol = stringTable + pSymbolTable->N.Name.Long;
-            }
-            std::string::size_type posAt = symbol.find('@');
-            if (posAt != std::string::npos) symbol.erase(posAt);
-#ifndef _MSC_VER
-            fprintf(fout, "\t%s\n", symbol.c_str());
-#else
-            fprintf(fout, "\t%s\n", symbol.c_str()+1);
-#endif
-         }
-      }
-
-      /*
-      * Take into account any aux symbols
-      */
-      i += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable++;
-   }
-}
-
-/*
 + * Utility func, strstr with size
 + */
 const char* StrNStr(const char* start, const char* find, size_t &size) {
@@ -443,7 +184,7 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER p
 */
 void
 DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
-                     FILE *fout, unsigned cSymbols, int fort)
+                     FILE *fout, unsigned cSymbols)
 {
    unsigned i;
    PSTR stringTable;
@@ -470,13 +211,7 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
             }
 
             while (isspace(symbol[0])) symbol.erase(0,1);
-#ifdef _MSC_VER
             if (symbol[0] == '_') symbol.erase(0,1);
-            if (fort) {
-               std::string::size_type posAt = symbol.find('@');
-               if (posAt != std::string::npos) symbol.erase(posAt);
-            }
-#endif
             if (fImportFlag) {
                fImportFlag = 0;
                fprintf(fout,"EXPORTS \n");
@@ -485,11 +220,6 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
             Check whether it is "Scalar deleting destructor" and
             "Vector deleting destructor"
             */
-            /*
-            if (!strstr(s,"@@UAEPAXI at Z") && !strstr(s,"@@QAEPAXI at Z") &&
-            !strstr(s,"@AEPAXI at Z")   && !strstr(s,"AEPAXI at Z")    &&
-            !strstr(s,"real@"))
-            */
             const char *scalarPrefix = "??_G";
             const char *vectorPrefix = "??_E";
             if (symbol.compare(0, 4, scalarPrefix) &&
@@ -544,7 +274,7 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
 *----------------------------------------------------------------------
 */
 void
-DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
+DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
 {
    PIMAGE_SYMBOL PCOFFSymbolTable;
    PIMAGE_SECTION_HEADER PCOFFSectionHeaders;
@@ -560,13 +290,9 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
       pImageFileHeader->SizeOfOptionalHeader);
 
 
-   if (full) {
-      DumpSymbolTable(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
-   } else {
-        int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
-        if (!haveExports)
-            DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount, fort);
-   }
+   int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
+   if (!haveExports)
+       DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
 }
 
 /*
@@ -578,7 +304,7 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
 *----------------------------------------------------------------------
 */
 void
-DumpFile(LPSTR filename, FILE *fout, int full, int fort)
+DumpFile(LPSTR filename, FILE *fout)
 {
    HANDLE hFile;
    HANDLE hFileMapping;
@@ -610,12 +336,8 @@ DumpFile(LPSTR filename, FILE *fout, int full, int fort)
 
    dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
    if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
-#if 0
-      DumpExeFile( dosHeader );
-#else
       fprintf(stderr, "File is an executable.  I don't dump those.\n");
       return;
-#endif
    }
    /* Does it look like a i386 COFF OBJ file??? */
    else if (
@@ -627,7 +349,7 @@ DumpFile(LPSTR filename, FILE *fout, int full, int fort)
       * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
       * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
       */
-      DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full, fort);
+      DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout);
    } else {
       printf("unrecognized file format\n");
    }
@@ -635,123 +357,3 @@ DumpFile(LPSTR filename, FILE *fout, int full, int fort)
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
 }
-
-void
-main(int argc, char **argv)
-{
-   std::string cmdline;
-   int i, arg;
-   FILE *fout;
-   int full = 0;
-   int fort = 0;
-   char *dllname = "";
-   char *outfile = NULL;
-
-   if (argc < 3) {
-Usage:
-      fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
-      exit(1);
-   }
-
-   arg = 1;
-   while (argv[arg][0] == '-') {
-      if (strcmp(argv[arg], "--") == 0) {
-         arg++;
-         break;
-      } else if (strcmp(argv[arg], "-f") == 0) {
-         full = 1;
-      } else if (strcmp(argv[arg], "-x") == 0) {
-         fort = 1;
-      } else if (strcmp(argv[arg], "-o") == 0) {
-         arg++;
-         if (arg == argc) {
-            goto Usage;
-         }
-         outfile = argv[arg];
-      }
-      arg++;
-   }
-   if (arg == argc) {
-      goto Usage;
-   }
-
-   if (outfile) {
-      fout = fopen(outfile, "w+");
-      if (fout == NULL) {
-         fprintf(stderr, "Unable to open \'%s\' for writing:\n",
-            argv[arg]);
-         perror("");
-         exit(1);
-      }
-   } else {
-      fout = stdout;
-   }
-
-   if (! full) {
-      dllname = argv[arg];
-      arg++;
-      if (arg == argc) {
-         goto Usage;
-      }
-      fprintf(fout, "LIBRARY    %s\n", dllname);
-#ifndef _X86_
-      fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
-      fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
-#endif
-   }
-
-   for (; arg < argc; arg++) {
-      WIN32_FIND_DATA FindFileData;
-      HANDLE SearchFile;
-      if (argv[arg][0] == '@') {
-         std::ifstream fargs(&argv[arg][1]);
-         if (!fargs) {
-            fprintf(stderr, "Unable to open \'%s\' for reading:\n",
-               argv[arg]);
-            perror("");
-            exit(1);
-         }
-         char *fargv[1000];
-         for (i = 0; i < arg; i++) {
-            cmdline += argv[i];
-            fargv[i] = argv[i];
-         }
-         std::string line;
-         std::getline(fargs, line);
-         cmdline += line;
-         fprintf(stderr, "%s\n", line.c_str());
-         i += GetArgcArgv(line, &fargv[i]);
-         argc = i;
-         argv = fargv;
-      }
-      /*
-      *  Argument can contain the wildcard names
-      */
-      SearchFile = FindFirstFile(argv[arg],&FindFileData);
-      if (SearchFile == INVALID_HANDLE_VALUE){
-         fprintf(stderr, "Unable to find \'%s\' for reading:\n",
-            argv[arg]);
-         exit(1);
-      }
-      else  {
-         /*
-         *  Since WIN32_FIND_DATA has no path information one has to extract it himself.
-         */
-         TCHAR *filename = argv[arg];
-         TCHAR path[2048];
-         size_t i = strlen(filename);
-         i--;
-         while( filename[i] != '\\' && filename[i] != '/'  && i >=0) i--;
-         do
-         {
-            if (i >= 0) strncpy( path, filename, i+1); /* Generate the 'path' info */
-            path[i+1] = '\0';
-            DumpFile(strcat(path, FindFileData.cFileName), fout, full, fort);
-         } while (FindNextFile(SearchFile,&FindFileData));
-
-
-         FindClose(SearchFile);
-      }
-   }
-   exit(0);
-}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e86309701d5d613a74fc8153c67a142c449c1d37
commit e86309701d5d613a74fc8153c67a142c449c1d37
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Jun 26 13:27:03 2015 -0400

    bindexplib: Add copyright/license notice block

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 6f9605c..a86318f 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -1,3 +1,21 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc.
+
+  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.
+============================================================================*/
+/*-------------------------------------------------------------------------
+  Portions of this source have been derived from the 'bindexplib' tool
+  provided by the CERN ROOT Data Analysis Framework project (root.cern.ch).
+  Permission has been granted by Pere Mato <pere.mato at cern.ch> to distribute
+  this derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
 /*
 *----------------------------------------------------------------------
 * Program:  dumpexts.exe

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3ef9d2461099cbfa69689df2ad84aefcbf38e34a
commit 3ef9d2461099cbfa69689df2ad84aefcbf38e34a
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Jun 26 13:26:52 2015 -0400

    bindexplib: Import original implementation from CERN
    
    Download the original implementation provided by root.cern.ch with the
    following session:
    
    $ wget https://raw.githubusercontent.com/gordonwatts/root-vc-port/f0ee59af/build/win/bindexplib/bindexplib.cxx
    $ sha1sum bindexplib.cxx
    fa6efafb2c58a0644bd0f6a56fe02ee0d55c7fcd  bindexplib.cxx
    $ sed -i 's/ *$//;s/'$'\t''/        /' bindexplib.cxx

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
new file mode 100644
index 0000000..6f9605c
--- /dev/null
+++ b/Source/bindexplib.cxx
@@ -0,0 +1,739 @@
+/*
+*----------------------------------------------------------------------
+* Program:  dumpexts.exe
+* Author:   Gordon Chaffee
+*
+* History:  The real functionality of this file was written by
+*           Matt Pietrek in 1993 in his pedump utility.  I've
+*           modified it to dump the externals in a bunch of object
+*           files to create a .def file.
+*
+* Notes:    Visual C++ puts an underscore before each exported symbol.
+*           This file removes them.  I don't know if this is a problem
+*           this other compilers.  If _MSC_VER is defined,
+*           the underscore is removed.  If not, it isn't.  To get a
+*           full dump of an object file, use the -f option.  This can
+*           help determine the something that may be different with a
+*           compiler other than Visual C++.
+*   ======================================
+* Corrections (Axel 2006-04-04):
+*   Conversion to C++. Mostly.
+*
+ * Extension (Axel 2006-03-15)
+ *    As soon as an object file contains an /EXPORT directive (which
+ *    is generated by the compiler when a symbol is declared as
+ *    declspec(dllexport)) no to-be-exported symbols are printed,
+ *    as the linker will see these directives, and if those directives
+ *    are present we only export selectively (i.e. we trust the
+ *    programmer).
+ *
+ *   ======================================
+*   ======================================
+* Corrections (Valery Fine 23/02/98):
+*
+*           The "(vector) deleting destructor" MUST not be exported
+*           To recognize it the following test are introduced:
+*  "@@UAEPAXI at Z"  scalar deleting dtor
+*  "@@QAEPAXI at Z"  vector deleting dtor
+*  "AEPAXI at Z"     vector deleting dtor with thunk adjustor
+*   ======================================
+* Corrections (Valery Fine 12/02/97):
+*
+*    It created a wrong EXPORTS for the global pointers and constants.
+*    The Section Header has been involved to discover the missing information
+*    Now the pointers are correctly supplied  supplied with "DATA" descriptor
+*        the constants  with no extra descriptor.
+*
+* Corrections (Valery Fine 16/09/96):
+*
+*     It didn't work for C++ code with global variables and class definitons
+*     The DumpExternalObject function has been introduced to generate .DEF file
+*
+* Author:   Valery Fine 16/09/96  (E-mail: fine at vxcern.cern.ch)
+*----------------------------------------------------------------------
+*/
+
+static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
+
+#include <windows.h>
+#include <stdio.h>
+#include <string>
+#include <fstream>
+
+/*
+*----------------------------------------------------------------------
+* GetArgcArgv --
+*
+*      Break up a line into argc argv
+*----------------------------------------------------------------------
+*/
+int
+GetArgcArgv(std::string &s, char **argv)
+{
+   int quote = 0;
+   int argc = 0;
+   std::string::iterator bp = s.begin();
+
+   while (1) {
+      while (isspace(*bp)) {
+         bp++;
+      }
+      if (*bp == '\n' || *bp == '\0') {
+         *bp = '\0';
+         return argc;
+      }
+      if (*bp == '\"') {
+         quote = 1;
+         bp++;
+      }
+      argv[argc++] = &(*bp);
+
+      while (*bp != '\0') {
+         if (quote) {
+            if (*bp == '\"') {
+               quote = 0;
+               *bp = '\0';
+               bp++;
+               break;
+            }
+            bp++;
+            continue;
+         }
+         if (isspace(*bp)) {
+            *bp = '\0';
+            bp++;
+            break;
+         }
+         bp++;
+      }
+   }
+}
+
+/*
+*  The names of the first group of possible symbol table storage classes
+*/
+char * SzStorageClass1[] = {
+   "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
+   "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
+   "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
+   "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
+};
+
+/*
+* The names of the second group of possible symbol table storage classes
+*/
+char * SzStorageClass2[] = {
+   "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
+};
+
+/*
+*----------------------------------------------------------------------
+* GetSZStorageClass --
+*
+*      Given a symbol storage class value, return a descriptive
+*      ASCII string
+*----------------------------------------------------------------------
+*/
+PSTR
+GetSZStorageClass(BYTE storageClass)
+{
+   if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
+      return SzStorageClass1[storageClass];
+   else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
+      && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
+      return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
+   else
+      return "???";
+}
+
+void AddHex(std::string& buf, long val, bool caps=false)
+{
+   buf += "0x";
+   size_t len=buf.length();
+   while (val) {
+      char hex = (char)(val & 16);
+      val = val >> 4;
+      if (hex<10) hex+='0';
+      else if (caps) hex+='A'-10;
+      else hex+='a'-10;
+      buf.insert(len, hex, 1);
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* GetSectionName --
+*
+*      Used by DumpSymbolTable, it gives meaningful names to
+*      the non-normal section number.
+*
+* Results:
+*      A name is returned in buffer
+*----------------------------------------------------------------------
+*/
+void
+GetSectionName(PIMAGE_SYMBOL pSymbolTable, std::string& buffer)
+{
+   DWORD section;
+
+   section = pSymbolTable->SectionNumber;
+
+   switch ( (SHORT)section )
+   {
+   case IMAGE_SYM_UNDEFINED: if (pSymbolTable->Value) buffer += "COMM"; else buffer += "UNDEF"; break;
+   case IMAGE_SYM_ABSOLUTE:  buffer += "ABS  "; break;
+   case IMAGE_SYM_DEBUG:     buffer += "DEBUG"; break;
+   default: AddHex(buffer, section, true);
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* GetSectionCharacteristics --
+*
+*      Converts the Characteristics field of IMAGE_SECTION_HEADER
+*      to print.
+*
+*  Results:
+*       A definiton of the section symbol type
+*----------------------------------------------------------------------
+*/
+void
+GetSectionCharacteristics(PIMAGE_SECTION_HEADER pSectionHeaders, int nSectNum, std::string &buffer)
+{
+   DWORD SectChar;
+   std::string TempBuf;
+   buffer.clear();
+   if (nSectNum > 0) {
+      SectChar = pSectionHeaders[nSectNum-1].Characteristics;
+
+      buffer = " ";
+      AddHex(buffer, SectChar);
+      if       (SectChar & IMAGE_SCN_CNT_CODE)                buffer += " Code";
+      else if  (SectChar & IMAGE_SCN_CNT_INITIALIZED_DATA)    buffer += " Init. data";
+      else if  (SectChar & IMAGE_SCN_CNT_UNINITIALIZED_DATA ) buffer += " UnInit data";
+      else                                                    buffer += " Unknow type";
+
+      if   (SectChar & IMAGE_SCN_MEM_READ)  {
+         buffer += " Read";
+         if (SectChar & IMAGE_SCN_MEM_WRITE)
+            buffer += " and Write";
+         else buffer += " only";
+      }
+      else if (SectChar & IMAGE_SCN_MEM_WRITE)
+         buffer +=" Write only";
+
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpSymbolTable --
+*
+*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
+*      it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout, unsigned cSymbols)
+{
+   unsigned i;
+   PSTR stringTable;
+   std::string sectionName;
+   std::string sectionCharacter;
+   int iSectNum;
+
+   fprintf(fout, "Symbol Table - %X entries  (* = auxillary symbol)\n",
+      cSymbols);
+
+   fprintf(fout,
+      "Indx Name                 Value    Section    cAux  Type    Storage  Character\n"
+      "---- -------------------- -------- ---------- ----- ------- -------- ---------\n");
+
+   /*
+   * The string table apparently starts right after the symbol table
+   */
+   stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+   for ( i=0; i < cSymbols; i++ ) {
+      fprintf(fout, "%04X ", i);
+      if ( pSymbolTable->N.Name.Short != 0 )
+         fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
+      else
+         fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
+
+      fprintf(fout, " %08X", pSymbolTable->Value);
+
+      iSectNum = pSymbolTable->SectionNumber;
+      GetSectionName(pSymbolTable, sectionName);
+      fprintf(fout, " sect:%s aux:%X type:%02X st:%s",
+         sectionName.c_str(),
+         pSymbolTable->NumberOfAuxSymbols,
+         pSymbolTable->Type,
+         GetSZStorageClass(pSymbolTable->StorageClass) );
+
+      GetSectionCharacteristics(pSectionHeaders,iSectNum,sectionCharacter);
+      fprintf(fout," hc: %s \n",sectionCharacter.c_str());
+#if 0
+      if ( pSymbolTable->NumberOfAuxSymbols )
+         DumpAuxSymbols(pSymbolTable);
+#endif
+
+      /*
+      * Take into account any aux symbols
+      */
+      i += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable++;
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpExternals --
+*
+*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
+*      it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
+{
+   unsigned i;
+   PSTR stringTable;
+   std::string symbol;
+
+   /*
+   * The string table apparently starts right after the symbol table
+   */
+   stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+   for ( i=0; i < cSymbols; i++ ) {
+      if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            if (pSymbolTable->N.Name.Short != 0) {
+               symbol = "";
+               symbol.insert(0, (const char *)(pSymbolTable->N.ShortName), 8);
+            } else {
+               symbol = stringTable + pSymbolTable->N.Name.Long;
+            }
+            std::string::size_type posAt = symbol.find('@');
+            if (posAt != std::string::npos) symbol.erase(posAt);
+#ifndef _MSC_VER
+            fprintf(fout, "\t%s\n", symbol.c_str());
+#else
+            fprintf(fout, "\t%s\n", symbol.c_str()+1);
+#endif
+         }
+      }
+
+      /*
+      * Take into account any aux symbols
+      */
+      i += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable++;
+   }
+}
+
+/*
++ * Utility func, strstr with size
++ */
+const char* StrNStr(const char* start, const char* find, size_t &size) {
+   size_t len;
+   const char* hint;
+
+   if (!start || !find || !size) {
+      size = 0;
+      return 0;
+   }
+   len = strlen(find);
+
+   while (hint = (const char*) memchr(start, find[0], size-len+1)) {
+      size -= (hint - start);
+      if (!strncmp(hint, find, len))
+         return hint;
+      start = hint + 1;
+   }
+
+   size = 0;
+   return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ * HaveExportedObjects --
+ *
+ *      Returns >0 if export directives (declspec(dllexport)) exist.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout)
+{
+    static int fImportFlag = 0;  /*  The status is nor defined yet */
+    WORD i;
+    size_t size;
+    char foundExports;
+    const char * rawdata;
+
+    PIMAGE_SECTION_HEADER pDirectivesSectionHeader;
+
+    if (fImportFlag) return 1;
+
+    i = 0;
+    foundExports = 0;
+    pDirectivesSectionHeader = 0;
+    for(i = 0; i < pImageFileHeader->NumberOfSections && !pDirectivesSectionHeader; i++)
+       if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
+          pDirectivesSectionHeader = &pSectionHeaders[i];
+   if (!pDirectivesSectionHeader) return 0;
+
+    rawdata=(const char*)pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
+    if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
+
+    size = pDirectivesSectionHeader->SizeOfRawData;
+    const char* posImportFlag = rawdata;
+    while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
+       const char* lookingForDict = posImportFlag + 9;
+       if (!strncmp(lookingForDict, "_G__cpp_",8) ||
+           !strncmp(lookingForDict, "_G__set_cpp_",12)) {
+          posImportFlag = lookingForDict;
+          continue;
+       }
+
+       const char* lookingForDATA = posImportFlag + 9;
+       while (*(++lookingForDATA) && *lookingForDATA != ' ');
+       lookingForDATA -= 5;
+       // ignore DATA exports
+       if (strncmp(lookingForDATA, ",DATA", 5)) break;
+       posImportFlag = lookingForDATA + 5;
+    }
+    fImportFlag = (int)posImportFlag;
+    return fImportFlag;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+* DumpExternalsObjects --
+*
+*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
+*      it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
+                     FILE *fout, unsigned cSymbols, int fort)
+{
+   unsigned i;
+   PSTR stringTable;
+   std::string symbol;
+   DWORD SectChar;
+   static int fImportFlag = -1;  /*  The status is nor defined yet */
+
+   /*
+   * The string table apparently starts right after the symbol table
+   */
+   stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+   for ( i=0; i < cSymbols; i++ ) {
+      if (pSymbolTable->SectionNumber > 0 && ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            /*
+            *    The name of the Function entry points
+            */
+            if (pSymbolTable->N.Name.Short != 0) {
+               symbol = "";
+               symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
+            } else {
+               symbol = stringTable + pSymbolTable->N.Name.Long;
+            }
+
+            while (isspace(symbol[0])) symbol.erase(0,1);
+#ifdef _MSC_VER
+            if (symbol[0] == '_') symbol.erase(0,1);
+            if (fort) {
+               std::string::size_type posAt = symbol.find('@');
+               if (posAt != std::string::npos) symbol.erase(posAt);
+            }
+#endif
+            if (fImportFlag) {
+               fImportFlag = 0;
+               fprintf(fout,"EXPORTS \n");
+            }
+            /*
+            Check whether it is "Scalar deleting destructor" and
+            "Vector deleting destructor"
+            */
+            /*
+            if (!strstr(s,"@@UAEPAXI at Z") && !strstr(s,"@@QAEPAXI at Z") &&
+            !strstr(s,"@AEPAXI at Z")   && !strstr(s,"AEPAXI at Z")    &&
+            !strstr(s,"real@"))
+            */
+            const char *scalarPrefix = "??_G";
+            const char *vectorPrefix = "??_E";
+            if (symbol.compare(0, 4, scalarPrefix) &&
+               symbol.compare(0, 4, vectorPrefix) &&
+               symbol.find("real@") == std::string::npos)
+            {
+               SectChar = pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+               if (!pSymbolTable->Type  && (SectChar & IMAGE_SCN_MEM_WRITE)) {
+                  // Read only (i.e. constants) must be excluded
+                  fprintf(fout, "\t%s \t DATA\n", symbol.c_str());
+               } else {
+                  if ( pSymbolTable->Type  || !(SectChar & IMAGE_SCN_MEM_READ)) {
+                     fprintf(fout, "\t%s\n", symbol.c_str());
+                  } else {
+                     //                    printf(" strange symbol: %s \n",s);
+                  }
+               }
+            }
+         }
+      }
+      else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && !pSymbolTable->Type && 0){
+         /*
+         *    The IMPORT global variable entry points
+         */
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            symbol = stringTable + pSymbolTable->N.Name.Long;
+            while (isspace(symbol[0]))  symbol.erase(0,1);
+            if (symbol[0] == '_') symbol.erase(0,1);
+            if (!fImportFlag) {
+               fImportFlag = 1;
+               fprintf(fout,"IMPORTS \n");
+            }
+            fprintf(fout, "\t%s DATA \n", symbol.c_str()+1);
+         }
+      }
+
+      /*
+      * Take into account any aux symbols
+      */
+      i += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable++;
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpObjFile --
+*
+*      Dump an object file--either a full listing or just the exported
+*      symbols.
+*----------------------------------------------------------------------
+*/
+void
+DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
+{
+   PIMAGE_SYMBOL PCOFFSymbolTable;
+   PIMAGE_SECTION_HEADER PCOFFSectionHeaders;
+   DWORD_PTR COFFSymbolCount;
+
+   PCOFFSymbolTable = (PIMAGE_SYMBOL)
+      ((DWORD_PTR)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
+   COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
+
+   PCOFFSectionHeaders = (PIMAGE_SECTION_HEADER)
+      ((DWORD_PTR)pImageFileHeader          +
+      IMAGE_SIZEOF_FILE_HEADER +
+      pImageFileHeader->SizeOfOptionalHeader);
+
+
+   if (full) {
+      DumpSymbolTable(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
+   } else {
+        int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
+        if (!haveExports)
+            DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount, fort);
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpFile --
+*
+*      Open up a file, memory map it, and call the appropriate
+*      dumping routine
+*----------------------------------------------------------------------
+*/
+void
+DumpFile(LPSTR filename, FILE *fout, int full, int fort)
+{
+   HANDLE hFile;
+   HANDLE hFileMapping;
+   LPVOID lpFileBase;
+   PIMAGE_DOS_HEADER dosHeader;
+
+   hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+   if (hFile == INVALID_HANDLE_VALUE) {
+      fprintf(stderr, "Couldn't open file with CreateFile()\n");
+      return;
+   }
+
+   hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+   if (hFileMapping == 0) {
+      CloseHandle(hFile);
+      fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
+      return;
+   }
+
+   lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+   if (lpFileBase == 0) {
+      CloseHandle(hFileMapping);
+      CloseHandle(hFile);
+      fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
+      return;
+   }
+
+   dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+   if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
+#if 0
+      DumpExeFile( dosHeader );
+#else
+      fprintf(stderr, "File is an executable.  I don't dump those.\n");
+      return;
+#endif
+   }
+   /* Does it look like a i386 COFF OBJ file??? */
+   else if (
+           ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) || (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+           && (dosHeader->e_sp == 0)
+           ) {
+      /*
+      * The two tests above aren't what they look like.  They're
+      * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
+      * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
+      */
+      DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full, fort);
+   } else {
+      printf("unrecognized file format\n");
+   }
+   UnmapViewOfFile(lpFileBase);
+   CloseHandle(hFileMapping);
+   CloseHandle(hFile);
+}
+
+void
+main(int argc, char **argv)
+{
+   std::string cmdline;
+   int i, arg;
+   FILE *fout;
+   int full = 0;
+   int fort = 0;
+   char *dllname = "";
+   char *outfile = NULL;
+
+   if (argc < 3) {
+Usage:
+      fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
+      exit(1);
+   }
+
+   arg = 1;
+   while (argv[arg][0] == '-') {
+      if (strcmp(argv[arg], "--") == 0) {
+         arg++;
+         break;
+      } else if (strcmp(argv[arg], "-f") == 0) {
+         full = 1;
+      } else if (strcmp(argv[arg], "-x") == 0) {
+         fort = 1;
+      } else if (strcmp(argv[arg], "-o") == 0) {
+         arg++;
+         if (arg == argc) {
+            goto Usage;
+         }
+         outfile = argv[arg];
+      }
+      arg++;
+   }
+   if (arg == argc) {
+      goto Usage;
+   }
+
+   if (outfile) {
+      fout = fopen(outfile, "w+");
+      if (fout == NULL) {
+         fprintf(stderr, "Unable to open \'%s\' for writing:\n",
+            argv[arg]);
+         perror("");
+         exit(1);
+      }
+   } else {
+      fout = stdout;
+   }
+
+   if (! full) {
+      dllname = argv[arg];
+      arg++;
+      if (arg == argc) {
+         goto Usage;
+      }
+      fprintf(fout, "LIBRARY    %s\n", dllname);
+#ifndef _X86_
+      fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
+      fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
+#endif
+   }
+
+   for (; arg < argc; arg++) {
+      WIN32_FIND_DATA FindFileData;
+      HANDLE SearchFile;
+      if (argv[arg][0] == '@') {
+         std::ifstream fargs(&argv[arg][1]);
+         if (!fargs) {
+            fprintf(stderr, "Unable to open \'%s\' for reading:\n",
+               argv[arg]);
+            perror("");
+            exit(1);
+         }
+         char *fargv[1000];
+         for (i = 0; i < arg; i++) {
+            cmdline += argv[i];
+            fargv[i] = argv[i];
+         }
+         std::string line;
+         std::getline(fargs, line);
+         cmdline += line;
+         fprintf(stderr, "%s\n", line.c_str());
+         i += GetArgcArgv(line, &fargv[i]);
+         argc = i;
+         argv = fargv;
+      }
+      /*
+      *  Argument can contain the wildcard names
+      */
+      SearchFile = FindFirstFile(argv[arg],&FindFileData);
+      if (SearchFile == INVALID_HANDLE_VALUE){
+         fprintf(stderr, "Unable to find \'%s\' for reading:\n",
+            argv[arg]);
+         exit(1);
+      }
+      else  {
+         /*
+         *  Since WIN32_FIND_DATA has no path information one has to extract it himself.
+         */
+         TCHAR *filename = argv[arg];
+         TCHAR path[2048];
+         size_t i = strlen(filename);
+         i--;
+         while( filename[i] != '\\' && filename[i] != '/'  && i >=0) i--;
+         do
+         {
+            if (i >= 0) strncpy( path, filename, i+1); /* Generate the 'path' info */
+            path[i+1] = '\0';
+            DumpFile(strcat(path, FindFileData.cFileName), fout, full, fort);
+         } while (FindNextFile(SearchFile,&FindFileData));
+
+
+         FindClose(SearchFile);
+      }
+   }
+   exit(0);
+}

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list