Просмотр исходного кода

Fix use of module .def files for MS tools

We recognize .def source files and map them to the /DEF:<file> option in
the MSVC tools.  Previously this worked only for shared libraries.  This
commit cleans up the implementation and makes it work for executables
too.  See issue #9613.
Brad King 16 лет назад
Родитель
Сommit
024d05adad

+ 7 - 21
Source/cmLocalVisualStudio7Generator.cxx

@@ -887,6 +887,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
   Options linkOptions(this, this->Version, Options::Linker,
                       cmLocalVisualStudio7GeneratorLinkFlagTable);
   linkOptions.Parse(extraLinkOptions.c_str());
+  if(!this->ModuleDefinitionFile.empty())
+    {
+    std::string defFile =
+      this->ConvertToXMLOutputPath(this->ModuleDefinitionFile.c_str());
+    linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
+    }
   switch(target.GetType())
     {
     case cmTarget::STATIC_LIBRARY:
@@ -960,7 +966,6 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
     fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
     this->OutputLibraryDirectories(fout, cli.GetDirectories());
     fout << "\"\n";
-    this->OutputModuleDefinitionFile(fout, target);
     temp = target.GetDirectory(configName);
     temp += "/";
     temp += targetNamePDB;
@@ -1080,26 +1085,6 @@ cmLocalVisualStudio7Generator
   fout << "\t\t\t\tVersion=\"" << major << "." << minor << "\"\n";
 }
 
-void cmLocalVisualStudio7Generator
-::OutputModuleDefinitionFile(std::ostream& fout,
-                             cmTarget &target)
-{
-  std::vector<cmSourceFile*> const& classes = target.GetSourceFiles();
-  for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
-      i != classes.end(); i++)
-    {
-    cmSourceFile* sf = *i;
-    if(cmSystemTools::UpperCase(sf->GetExtension()) == "DEF")
-      {
-      fout << "\t\t\t\tModuleDefinitionFile=\""
-           << this->ConvertToXMLOutputPath(sf->GetFullPath().c_str())
-           << "\"\n";
-      return;
-      }
-    }
-
-}
-
 //----------------------------------------------------------------------------
 void
 cmLocalVisualStudio7GeneratorInternals
@@ -1174,6 +1159,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
 
   // get the classes from the source lists then add them to the groups
+  this->ModuleDefinitionFile = "";
   std::vector<cmSourceFile*>const & classes = target.GetSourceFiles();
   for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
       i != classes.end(); i++)

+ 0 - 1
Source/cmLocalVisualStudio7Generator.h

@@ -102,7 +102,6 @@ private:
                        cmTarget& t, bool debug);
   void OutputLibraryDirectories(std::ostream& fout,
                                 std::vector<std::string> const& dirs);
-  void OutputModuleDefinitionFile(std::ostream& fout, cmTarget &target);
   void WriteProjectStart(std::ostream& fout, const char *libName,
                          cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
   void WriteProjectStartFortran(std::ostream& fout, const char *libName,

+ 2 - 0
Source/cmMakefileExecutableTargetGenerator.cxx

@@ -243,6 +243,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   this->LocalGenerator->AppendFlags
     (linkFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
 
+  this->AddModuleDefinitionFlag(linkFlags);
+
   // Construct a list of files associated with this executable that
   // may need to be cleaned.
   std::vector<std::string> exeCleanFiles;

+ 3 - 23
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -146,27 +146,8 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
                                     
   this->LocalGenerator->AddConfigVariableFlags
     (extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
-  if(this->Makefile->IsOn("WIN32") && !(this->Makefile->IsOn("CYGWIN") 
-                                        || this->Makefile->IsOn("MINGW")))
-    {
-    const std::vector<cmSourceFile*>& sources = 
-      this->Target->GetSourceFiles();
-    for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
-        i != sources.end(); ++i)
-      {
-      cmSourceFile* sf = *i;
-      if(sf->GetExtension() == "def")
-        {
-        extraFlags += " ";
-        extraFlags += 
-          this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
-        extraFlags += 
-          this->Convert(sf->GetFullPath().c_str(),
-                        cmLocalGenerator::START_OUTPUT,
-                        cmLocalGenerator::SHELL);
-        }
-      }
-    }
+  this->AddModuleDefinitionFlag(extraFlags);
+
   this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
 }
 
@@ -191,8 +172,8 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
     (extraFlags, this->Target->GetProperty(linkFlagsConfig.c_str()));
   this->LocalGenerator->AddConfigVariableFlags
     (extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
+  this->AddModuleDefinitionFlag(extraFlags);
 
-  // TODO: .def files should be supported here also.
   this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
 }
 
@@ -218,7 +199,6 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
   this->LocalGenerator->AddConfigVariableFlags
     (extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
 
-  // TODO: .def files should be supported here also.
   this->WriteLibraryRules(linkRuleVar.c_str(), extraFlags.c_str(), relink);
 }
 

+ 28 - 0
Source/cmMakefileTargetGenerator.cxx

@@ -170,6 +170,10 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
         // This is an external object file.  Just add it.
         this->ExternalObjects.push_back((*source)->GetFullPath());
         }
+      else if(cmSystemTools::UpperCase((*source)->GetExtension()) == "DEF")
+        {
+        this->ModuleDefinitionFile = (*source)->GetFullPath();
+        }
       else
         {
         // We only get here if a source file is not an external object
@@ -1734,3 +1738,27 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
       }
     }
 }
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
+{
+  if(this->ModuleDefinitionFile.empty())
+    {
+    return;
+    }
+
+  // TODO: Create a per-language flag variable.
+  const char* defFileFlag =
+    this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+  if(!defFileFlag)
+    {
+    return;
+    }
+
+  // Append the flag and value.
+  std::string flag = defFileFlag;
+  flag += this->Convert(this->ModuleDefinitionFile.c_str(),
+                        cmLocalGenerator::START_OUTPUT,
+                        cmLocalGenerator::SHELL);
+  this->LocalGenerator->AppendFlags(flags, flag.c_str());
+}

+ 6 - 0
Source/cmMakefileTargetGenerator.h

@@ -186,6 +186,9 @@ protected:
   std::vector<std::string> Objects;
   std::vector<std::string> ExternalObjects;
 
+  // The windows module definition source file (.def), if any.
+  std::string ModuleDefinitionFile;
+
   // Set of object file names that will be built in this directory.
   std::set<cmStdString> ObjectFiles;
 
@@ -214,6 +217,9 @@ protected:
   // Compute target-specific Fortran language flags.
   void AddFortranFlags(std::string& flags);
 
+  // Helper to add flag for windows .def file.
+  void AddModuleDefinitionFlag(std::string& flags);
+
   //==================================================================
   // Convenience routines that do nothing more than forward to
   // implementaitons

+ 5 - 0
Source/cmVisualStudio10TargetGenerator.cxx

@@ -1125,6 +1125,11 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
   linkOptions.AddFlag("ImportLibrary", imLib.c_str());
   linkOptions.AddFlag("ProgramDataBaseFileName", pdb.c_str());
   linkOptions.Parse(flags.c_str());
+  if(!this->ModuleDefinitionFile.empty())
+    {
+    linkOptions.AddFlag("ModuleDefinitionFile",
+                        this->ModuleDefinitionFile.c_str());
+    }
   linkOptions.OutputAdditionalOptions(*this->BuildFileStream, "      ", "");
   linkOptions.OutputFlagMap(*this->BuildFileStream, "      ");