Browse Source

Fortran: Refactor to treat .mod extension as part of module name

When tracking module names internally, include the `.mod` extension.
This will later be useful to distinguish them from `.smod` extensions
for submodules.
Brad King 7 years ago
parent
commit
62538b2c4c

+ 37 - 19
Source/cmDependsFortran.cxx

@@ -10,6 +10,7 @@
 #include <string.h>
 #include <utility>
 
+#include "cmAlgorithms.h"
 #include "cmFortranParser.h" /* Interface to parser object.  */
 #include "cmGeneratedFileStream.h"
 #include "cmLocalGenerator.h"
@@ -23,6 +24,20 @@
 // use lower case and some always use upper case.  I do not know if any
 // use the case from the source code.
 
+static void cmFortranModuleAppendUpperLower(std::string const& mod,
+                                            std::string& mod_upper,
+                                            std::string& mod_lower)
+{
+  std::string::size_type ext_len = 0;
+  if (cmHasLiteralSuffix(mod, ".mod")) {
+    ext_len = 4;
+  }
+  std::string const& name = mod.substr(0, mod.size() - ext_len);
+  std::string const& ext = mod.substr(mod.size() - ext_len);
+  mod_upper += cmSystemTools::UpperCase(name) + ext;
+  mod_lower += mod;
+}
+
 class cmDependsFortranInternals
 {
 public:
@@ -181,16 +196,13 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
     for (std::string const& i : provides) {
       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";
+      cmFortranModuleAppendUpperLower(i, mod_upper, mod_lower);
       std::string stamp = stamp_dir;
       stamp += "/";
       stamp += i;
-      stamp += ".mod.stamp";
+      stamp += ".stamp";
       fcStream << "\n";
       fcStream << "  \""
                << this->MaybeConvertToRelativePath(currentBinDir, mod_lower)
@@ -270,7 +282,13 @@ void cmDependsFortran::MatchRemoteModules(std::istream& fin,
 
     if (line[0] == ' ') {
       if (doing_provides) {
-        this->ConsiderModule(line.c_str() + 1, stampDir);
+        std::string mod = line;
+        if (!cmHasLiteralSuffix(mod, ".mod")) {
+          // Support fortran.internal files left by older versions of CMake.
+          // They do not include the ".mod" extension.
+          mod += ".mod";
+        }
+        this->ConsiderModule(mod.c_str() + 1, stampDir);
       }
     } else if (line == "provides") {
       doing_provides = true;
@@ -292,7 +310,7 @@ void cmDependsFortran::ConsiderModule(const char* name, const char* stampDir)
     std::string stampFile = stampDir;
     stampFile += "/";
     stampFile += name;
-    stampFile += ".mod.stamp";
+    stampFile += ".stamp";
     required->second = stampFile;
   }
 }
@@ -366,7 +384,6 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
       // Always use lower case for the mod stamp file name.  The
       // cmake_copy_f90_mod will call back to this class, which will
       // try various cases for the real mod file name.
-      std::string m = cmSystemTools::LowerCase(i);
       std::string modFile = mod_dir;
       modFile += "/";
       modFile += i;
@@ -375,8 +392,8 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
         cmOutputConverter::SHELL);
       std::string stampFile = stamp_dir;
       stampFile += "/";
-      stampFile += m;
-      stampFile += ".mod.stamp";
+      stampFile += i;
+      stampFile += ".stamp";
       stampFile = this->MaybeConvertToRelativePath(binDir, stampFile);
       std::string const stampFileForShell =
         this->LocalGenerator->ConvertToOutputFormat(stampFile,
@@ -423,10 +440,9 @@ bool cmDependsFortran::WriteDependenciesReal(const char* obj,
 bool cmDependsFortran::FindModule(std::string const& name, std::string& module)
 {
   // Construct possible names for the module file.
-  std::string mod_upper = cmSystemTools::UpperCase(name);
-  std::string mod_lower = name;
-  mod_upper += ".mod";
-  mod_lower += ".mod";
+  std::string mod_upper;
+  std::string mod_lower;
+  cmFortranModuleAppendUpperLower(name, mod_upper, mod_lower);
 
   // Search the include path for the module.
   std::string fullName;
@@ -470,17 +486,19 @@ bool cmDependsFortran::CopyModule(const std::vector<std::string>& args)
   if (args.size() >= 5) {
     compilerId = args[4];
   }
+  if (!cmHasLiteralSuffix(mod, ".mod")) {
+    // Support depend.make files left by older versions of CMake.
+    // They do not include the ".mod" extension.
+    mod += ".mod";
+  }
   std::string mod_dir = cmSystemTools::GetFilenamePath(mod);
   if (!mod_dir.empty()) {
     mod_dir += "/";
   }
   std::string mod_upper = mod_dir;
-  mod_upper += cmSystemTools::UpperCase(cmSystemTools::GetFilenameName(mod));
   std::string mod_lower = mod_dir;
-  mod_lower += cmSystemTools::LowerCase(cmSystemTools::GetFilenameName(mod));
-  mod += ".mod";
-  mod_upper += ".mod";
-  mod_lower += ".mod";
+  cmFortranModuleAppendUpperLower(cmSystemTools::GetFilenameName(mod),
+                                  mod_upper, mod_lower);
   if (cmSystemTools::FileExists(mod_upper, true)) {
     if (cmDependsFortran::ModulesDiffer(mod_upper.c_str(), stamp.c_str(),
                                         compilerId.c_str())) {

+ 3 - 2
Source/cmFortranParser.h

@@ -39,11 +39,12 @@ int cmFortranParser_GetOldStartcond(cmFortranParser* parser);
 
 /* Callbacks for parser.  */
 void cmFortranParser_Error(cmFortranParser* parser, const char* message);
-void cmFortranParser_RuleUse(cmFortranParser* parser, const char* name);
+void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name);
 void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
                                        const char* filename);
 void cmFortranParser_RuleInclude(cmFortranParser* parser, const char* name);
-void cmFortranParser_RuleModule(cmFortranParser* parser, const char* name);
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+                                const char* module_name);
 void cmFortranParser_RuleDefine(cmFortranParser* parser, const char* name);
 void cmFortranParser_RuleUndef(cmFortranParser* parser, const char* name);
 void cmFortranParser_RuleIfdef(cmFortranParser* parser, const char* name);

+ 19 - 6
Source/cmFortranParserImpl.cxx

@@ -168,11 +168,16 @@ void cmFortranParser_Error(cmFortranParser* parser, const char* msg)
   parser->Error = msg ? msg : "unknown error";
 }
 
-void cmFortranParser_RuleUse(cmFortranParser* parser, const char* name)
+void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name)
 {
-  if (!parser->InPPFalseBranch) {
-    parser->Info.Requires.insert(cmSystemTools::LowerCase(name));
+  if (parser->InPPFalseBranch) {
+    return;
   }
+
+  // syntax:   "use module_name"
+  // requires: "module_name.mod"
+  std::string const& mod_name = cmSystemTools::LowerCase(module_name);
+  parser->Info.Requires.insert(mod_name + ".mod");
 }
 
 void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
@@ -225,10 +230,18 @@ void cmFortranParser_RuleInclude(cmFortranParser* parser, const char* name)
   }
 }
 
-void cmFortranParser_RuleModule(cmFortranParser* parser, const char* name)
+void cmFortranParser_RuleModule(cmFortranParser* parser,
+                                const char* module_name)
 {
-  if (!parser->InPPFalseBranch && !parser->InInterface) {
-    parser->Info.Provides.insert(cmSystemTools::LowerCase(name));
+  if (parser->InPPFalseBranch) {
+    return;
+  }
+
+  if (!parser->InInterface) {
+    // syntax:   "module module_name"
+    // provides: "module_name.mod"
+    std::string const& mod_name = cmSystemTools::LowerCase(module_name);
+    parser->Info.Provides.insert(mod_name + ".mod");
   }
 }
 

+ 1 - 1
Source/cmGlobalNinjaGenerator.cxx

@@ -1812,7 +1812,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
   Json::Value tm = Json::objectValue;
   for (cmFortranObjectInfo const& object : objects) {
     for (std::string const& p : object.Provides) {
-      std::string const mod = module_dir + p + ".mod";
+      std::string const mod = module_dir + p;
       mod_files[p] = mod;
       tm[p] = mod;
     }