[cmake-commits] king committed cmDependsFortran.cxx 1.36 1.37 cmDependsFortran.h 1.10 1.11 cmDocumentVariables.cxx 1.7 1.8 cmMakefileTargetGenerator.cxx 1.80 1.81 cmMakefileTargetGenerator.h 1.18 1.19 cmTarget.cxx 1.169 1.170

cmake-commits at cmake.org cmake-commits at cmake.org
Sun Dec 30 16:11:40 EST 2007


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv20471/Source

Modified Files:
	cmDependsFortran.cxx cmDependsFortran.h 
	cmDocumentVariables.cxx cmMakefileTargetGenerator.cxx 
	cmMakefileTargetGenerator.h cmTarget.cxx 
Log Message:
ENH: Implemented Fortran module output directory and search path flags.


Index: cmDependsFortran.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDependsFortran.cxx,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- cmDependsFortran.cxx	30 Dec 2007 17:23:54 -0000	1.36
+++ cmDependsFortran.cxx	30 Dec 2007 21:11:38 -0000	1.37
@@ -194,6 +194,23 @@
   // Prepare the module search process.
   this->LocateModules();
 
+  // Get the directory in which stamp files will be stored.
+  const char* stamp_dir =
+    this->LocalGenerator->GetMakefile()->GetCurrentOutputDirectory();
+
+  // Get the directory in which module files will be created.
+  const char* mod_dir;
+  cmMakefile* mf = this->LocalGenerator->GetMakefile();
+  if(const char* target_mod_dir =
+     mf->GetDefinition("CMAKE_Fortran_TARGET_MODULE_DIR"))
+    {
+    mod_dir = target_mod_dir;
+    }
+  else
+    {
+    mod_dir = stamp_dir;
+    }
+
   // Actually write dependencies to the streams.
   typedef cmDependsFortranInternals::ObjectInfoMap ObjectInfoMap;
   ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
@@ -201,6 +218,7 @@
       i != objInfo.end(); ++i)
     {
     if(!this->WriteDependenciesReal(i->first.c_str(), i->second,
+                                    mod_dir, stamp_dir,
                                     makeDepends, internalDepends))
       {
       return false;
@@ -227,16 +245,35 @@
     fcName += "/cmake_clean_Fortran.cmake";
     cmGeneratedFileStream fcStream(fcName.c_str());
     fcStream << "# Remove fortran modules provided by this target.\n";
-    fcStream << "FILE(REMOVE\n";
+    fcStream << "FILE(REMOVE";
     for(std::set<cmStdString>::const_iterator i = provides.begin();
         i != provides.end(); ++i)
       {
-      std::string mod_upper = cmSystemTools::UpperCase(*i);
-      std::string mod_lower = *i;
-      fcStream << " \"" << mod_lower << ".mod\""
-               << " \"" << mod_lower << ".mod.stamp\""
-               << " \"" << mod_upper << ".mod\""
-               << " \"" << mod_upper << ".mod.stamp\"\n";
+      std::string mod_upper = mod_dir;
+      mod_upper += "/";
+      mod_upper += cmSystemTools::UpperCase(*i);
+      mod_upper += ".mod";
+      std::string mod_lower = mod_dir;
+      mod_lower += "/";
+      mod_lower += *i;
+      mod_lower += ".mod";
+      std::string stamp = stamp_dir;
+      stamp += "/";
+      stamp += *i;
+      stamp += ".mod.stamp";
+      fcStream << "\n";
+      fcStream << "  \"" <<
+        this->LocalGenerator->Convert(mod_lower.c_str(),
+                                      cmLocalGenerator::START_OUTPUT)
+               << "\"\n";
+      fcStream << "  \"" <<
+        this->LocalGenerator->Convert(mod_upper.c_str(),
+                                      cmLocalGenerator::START_OUTPUT)
+               << "\"\n";
+      fcStream << "  \"" <<
+        this->LocalGenerator->Convert(stamp.c_str(),
+                                      cmLocalGenerator::START_OUTPUT)
+               << "\"\n";
       }
     fcStream << "  )\n";
     }
@@ -304,19 +341,19 @@
 //----------------------------------------------------------------------------
 void cmDependsFortran::MatchLocalModules()
 {
-  const char* moduleDir =
+  const char* stampDir =
     this->LocalGenerator->GetMakefile()->GetCurrentOutputDirectory();
   std::set<cmStdString> const& provides = this->Internal->TargetProvides;
   for(std::set<cmStdString>::const_iterator i = provides.begin();
       i != provides.end(); ++i)
     {
-    this->ConsiderModule(i->c_str(), moduleDir);
+    this->ConsiderModule(i->c_str(), stampDir);
     }
 }
 
 //----------------------------------------------------------------------------
 void cmDependsFortran::MatchRemoteModules(std::istream& fin,
-                                          const char* moduleDir)
+                                          const char* stampDir)
 {
   std::string line;
   bool doing_provides = false;
@@ -332,7 +369,7 @@
       {
       if(doing_provides)
         {
-        this->ConsiderModule(line.c_str()+1, moduleDir);
+        this->ConsiderModule(line.c_str()+1, stampDir);
         }
       }
     else if(line == "provides")
@@ -348,7 +385,7 @@
 
 //----------------------------------------------------------------------------
 void cmDependsFortran::ConsiderModule(const char* name,
-                                      const char* moduleDir)
+                                      const char* stampDir)
 {
   // Locate each required module.
   typedef cmDependsFortranInternals::TargetRequiresMap TargetRequiresMap;
@@ -358,7 +395,7 @@
      required->second.empty())
     {
     // The module is provided by a CMake target.  It will have a stamp file.
-    std::string stampFile = moduleDir;
+    std::string stampFile = stampDir;
     stampFile += "/";
     stampFile += name;
     stampFile += ".mod.stamp";
@@ -371,6 +408,7 @@
 cmDependsFortran
 ::WriteDependenciesReal(const char *obj,
                         cmDependsFortranSourceInfo const& info,
+                        const char* mod_dir, const char* stamp_dir,
                         std::ostream& makeDepends,
                         std::ostream& internalDepends)
 {
@@ -379,10 +417,6 @@
   // Get the source file for this object.
   const char* src = info.Source.c_str();
 
-  // Get the directory in which stamp files will be stored.
-  std::string mod_dir =
-    this->LocalGenerator->GetMakefile()->GetCurrentOutputDirectory();
-
   // Write the include dependencies to the output stream.
   internalDepends << obj << std::endl;
   internalDepends << " " << src << std::endl;
@@ -414,7 +448,7 @@
       // The module is provided by a different source in the same
       // target.  Add the proxy dependency to make sure the other
       // source builds first.
-      std::string proxy = mod_dir;
+      std::string proxy = stamp_dir;
       proxy += "/";
       proxy += *i;
       proxy += ".mod.proxy";
@@ -460,7 +494,7 @@
   for(std::set<cmStdString>::const_iterator i = info.Provides.begin();
       i != info.Provides.end(); ++i)
     {
-    std::string proxy = mod_dir;
+    std::string proxy = stamp_dir;
     proxy += "/";
     proxy += *i;
     proxy += ".mod.proxy";
@@ -493,7 +527,7 @@
         this->LocalGenerator->Convert(modFile.c_str(),
                                       cmLocalGenerator::HOME_OUTPUT,
                                       cmLocalGenerator::SHELL);
-      std::string stampFile = mod_dir;
+      std::string stampFile = stamp_dir;
       stampFile += "/";
       stampFile += m;
       stampFile += ".mod.stamp";

Index: cmDependsFortran.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDependsFortran.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- cmDependsFortran.h	28 Dec 2007 16:49:59 -0000	1.10
+++ cmDependsFortran.h	30 Dec 2007 21:11:38 -0000	1.11
@@ -60,8 +60,8 @@
   // Find all the modules required by the target.
   void LocateModules();
   void MatchLocalModules();
-  void MatchRemoteModules(std::istream& fin, const char* moduleDir);
-  void ConsiderModule(const char* name, const char* moduleDir);
+  void MatchRemoteModules(std::istream& fin, const char* stampDir);
+  void ConsiderModule(const char* name, const char* stampDir);
   bool FindModule(std::string const& name, std::string& module);
 
   // Implement writing/checking methods required by superclass.
@@ -72,6 +72,7 @@
   // Actually write the depenencies to the streams.
   bool WriteDependenciesReal(const char *obj,
                              cmDependsFortranSourceInfo const& info,
+                             const char* mod_dir, const char* stamp_dir,
                              std::ostream& makeDepends,
                              std::ostream& internalDepends);
 

Index: cmDocumentVariables.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDocumentVariables.cxx,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- cmDocumentVariables.cxx	10 Nov 2007 13:14:13 -0000	1.7
+++ cmDocumentVariables.cxx	30 Dec 2007 21:11:38 -0000	1.8
@@ -680,6 +680,15 @@
      "Variables that Control the Build");
 
   cm->DefineProperty
+    ("CMAKE_Fortran_MODULE_DIRECTORY", cmProperty::VARIABLE,
+     "Fortran module output directory.",
+     "This variable is used to initialize the "
+     "Fortran_MODULE_DIRECTORY property on all the targets. "
+     "See that target property for additional information.",
+     false,
+     "Variables that Control the Build");
+
+  cm->DefineProperty
     ("CMAKE_LIBRARY_OUTPUT_DIRECTORY", cmProperty::VARIABLE,
      "Where to put all the LIBRARY targets when built.",
      "This variable is used to initialize the "

Index: cmMakefileTargetGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefileTargetGenerator.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- cmMakefileTargetGenerator.h	28 Dec 2007 19:59:06 -0000	1.18
+++ cmMakefileTargetGenerator.h	30 Dec 2007 21:11:38 -0000	1.19
@@ -184,6 +184,14 @@
   typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
   MultipleOutputPairsType MultipleOutputPairs;
 
+  // Target-wide Fortran module output directory.
+  bool FortranModuleDirectoryComputed;
+  std::string FortranModuleDirectory;
+  const char* GetFortranModuleDirectory();
+
+  // Compute target-specific Fortran language flags.
+  void AddFortranFlags(std::string& flags);
+
   //==================================================================
   // Convenience routines that do nothing more than forward to
   // implementaitons

Index: cmMakefileTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefileTargetGenerator.cxx,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -d -r1.80 -r1.81
--- cmMakefileTargetGenerator.cxx	28 Dec 2007 19:59:06 -0000	1.80
+++ cmMakefileTargetGenerator.cxx	30 Dec 2007 21:11:38 -0000	1.81
@@ -36,6 +36,7 @@
   this->InfoFileStream = 0;
   this->FlagFileStream = 0;
   this->CustomCommandDriver = OnBuild;
+  this->FortranModuleDirectoryComputed = false;
 }
 
 cmMakefileTargetGenerator *
@@ -268,6 +269,12 @@
       ->AddLanguageFlags(flags, lang,
                          this->LocalGenerator->ConfigurationName.c_str());
 
+    // Fortran-specific flags computed for this target.
+    if(*l == "Fortran")
+      {
+      this->AddFortranFlags(flags);
+      }
+
     // Add shared-library flags if needed.
     this->LocalGenerator->AddSharedFlags(flags, lang, shared);
 
@@ -823,6 +830,15 @@
     << "  )\n";
   }
 
+  // Check for a target-specific module output directory.
+  if(const char* mdir = this->GetFortranModuleDirectory())
+    {
+    *this->InfoFileStream
+      << "\n"
+      << "# Fortran module output directory.\n"
+      << "SET(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n";
+    }
+
   // and now write the rule to use it
   std::vector<std::string> depends;
   std::vector<std::string> commands;
@@ -1423,3 +1439,82 @@
   link_command += " --verbose=$(VERBOSE)";
   makefile_commands.push_back(link_command);
 }
+
+//----------------------------------------------------------------------------
+const char* cmMakefileTargetGenerator::GetFortranModuleDirectory()
+{
+  // Compute the module directory.
+  if(!this->FortranModuleDirectoryComputed)
+    {
+    const char* target_mod_dir =
+      this->Target->GetProperty("Fortran_MODULE_DIRECTORY");
+    const char* moddir_flag =
+      this->Makefile->GetDefinition("CMAKE_Fortran_MODDIR_FLAG");
+    if(target_mod_dir && moddir_flag)
+      {
+      // Compute the full path to the module directory.
+      if(cmSystemTools::FileIsFullPath(target_mod_dir))
+        {
+        // Already a full path.
+        this->FortranModuleDirectory = target_mod_dir;
+        }
+      else
+        {
+        // Interpret relative to the current output directory.
+        this->FortranModuleDirectory =
+          this->Makefile->GetCurrentOutputDirectory();
+        this->FortranModuleDirectory += "/";
+        this->FortranModuleDirectory += target_mod_dir;
+        }
+
+      // Make sure the module output directory exists.
+      cmSystemTools::MakeDirectory(this->FortranModuleDirectory.c_str());
+      }
+    this->FortranModuleDirectoryComputed = true;
+    }
+
+  // Return the computed directory.
+  if(this->FortranModuleDirectory.empty())
+    {
+    return 0;
+    }
+  else
+    {
+    return this->FortranModuleDirectory.c_str();
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
+{
+  // Add a module output directory flag if necessary.
+  if(const char* mod_dir = this->GetFortranModuleDirectory())
+    {
+    const char* moddir_flag =
+      this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG");
+    std::string modflag = moddir_flag;
+    modflag += this->Convert(mod_dir,
+                             cmLocalGenerator::START_OUTPUT,
+                             cmLocalGenerator::SHELL);
+    this->LocalGenerator->AppendFlags(flags, modflag.c_str());
+    }
+
+  // If there is a separate module path flag then duplicate the
+  // include path with it.  This compiler does not search the include
+  // path for modules.
+  if(const char* modpath_flag =
+     this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG"))
+    {
+    std::vector<std::string> includes;
+    this->LocalGenerator->GetIncludeDirectories(includes);
+    for(std::vector<std::string>::const_iterator idi = includes.begin();
+        idi != includes.end(); ++idi)
+      {
+      std::string flg = modpath_flag;
+      flg += this->Convert(idi->c_str(),
+                           cmLocalGenerator::NONE,
+                           cmLocalGenerator::SHELL);
+      this->LocalGenerator->AppendFlags(flags, flg.c_str());
+      }
+    }
+}

Index: cmTarget.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.cxx,v
retrieving revision 1.169
retrieving revision 1.170
diff -u -d -r1.169 -r1.170
--- cmTarget.cxx	18 Dec 2007 22:50:27 -0000	1.169
+++ cmTarget.cxx	30 Dec 2007 21:11:38 -0000	1.170
@@ -285,6 +285,15 @@
      "All Windows-based systems including Cygwin are DLL platforms.");
 
   cm->DefineProperty
+    ("Fortran_MODULE_DIRECTORY", cmProperty::TARGET,
+     "Specify output directory for Fortran modules provided by the target.",
+     "If the target contains Fortran source files that provide modules "
+     "and the compiler supports a module output directory this specifies "
+     "the directory in which the modules will be placed.  "
+     "When this property is not set the modules will be placed in the "
+     "build directory corresponding to the target's source directory.");
+
+  cm->DefineProperty
     ("XCODE_ATTRIBUTE_<an-attribute>", cmProperty::TARGET,
      "Set Xcode target attributes directly.",
      "Tell the Xcode generator to set '<an-attribute>' to a given value "
@@ -403,6 +412,7 @@
   this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0);
   this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0);
   this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
+  this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
 
   // Collect the set of configuration types.
   std::vector<std::string> configNames;



More information about the Cmake-commits mailing list