Merge topic 'fortran-submodule-names'

d80ecba5c2 Fortran: Fix submodule file names across compilers
72057d9c15 Fortran: Thread compiler id through to internal Fortran parser
7ae329e2ed Fortran: Factor out .mod and .smod file name construction

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Michael Hirsch, Ph.D. <michael@scivision.co>
Merge-request: !2958
diff --git a/Modules/Compiler/Flang-Fortran.cmake b/Modules/Compiler/Flang-Fortran.cmake
index d522739..f0e61d8 100644
--- a/Modules/Compiler/Flang-Fortran.cmake
+++ b/Modules/Compiler/Flang-Fortran.cmake
@@ -1,6 +1,9 @@
 include(Compiler/Clang)
 __compiler_clang(Fortran)
 
+set(CMAKE_Fortran_SUBMODULE_SEP "-")
+set(CMAKE_Fortran_SUBMODULE_EXT ".mod")
+
 set(CMAKE_Fortran_PREPROCESS_SOURCE
     "<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 
diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake
index c333d50..6413769 100644
--- a/Modules/Compiler/GNU-Fortran.cmake
+++ b/Modules/Compiler/GNU-Fortran.cmake
@@ -1,6 +1,9 @@
 include(Compiler/GNU)
 __compiler_gnu(Fortran)
 
+set(CMAKE_Fortran_SUBMODULE_SEP "@")
+set(CMAKE_Fortran_SUBMODULE_EXT ".smod")
+
 set(CMAKE_Fortran_PREPROCESS_SOURCE
   "<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> -o <PREPROCESSED_SOURCE>")
 
diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake
index a132055..5275ddf 100644
--- a/Modules/Compiler/Intel-Fortran.cmake
+++ b/Modules/Compiler/Intel-Fortran.cmake
@@ -1,6 +1,9 @@
 include(Compiler/Intel)
 __compiler_intel(Fortran)
 
+set(CMAKE_Fortran_SUBMODULE_SEP "@")
+set(CMAKE_Fortran_SUBMODULE_EXT ".smod")
+
 set(CMAKE_Fortran_MODDIR_FLAG "-module ")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake
index a183c33..3daf798 100644
--- a/Modules/Compiler/PGI-Fortran.cmake
+++ b/Modules/Compiler/PGI-Fortran.cmake
@@ -1,6 +1,9 @@
 include(Compiler/PGI)
 __compiler_pgi(Fortran)
 
+set(CMAKE_Fortran_SUBMODULE_SEP "-")
+set(CMAKE_Fortran_SUBMODULE_EXT ".mod")
+
 set(CMAKE_Fortran_PREPROCESS_SOURCE
   "<CMAKE_Fortran_COMPILER> -Mpreprocess <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 
diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake
index 6bab6f6..c4fb097 100644
--- a/Modules/Compiler/XL-Fortran.cmake
+++ b/Modules/Compiler/XL-Fortran.cmake
@@ -1,6 +1,9 @@
 include(Compiler/XL)
 __compiler_xl(Fortran)
 
+set(CMAKE_Fortran_SUBMODULE_SEP "_")
+set(CMAKE_Fortran_SUBMODULE_EXT ".smod")
+
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-qfixed") # [=<right_margin>]
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-qfree") # [=f90|ibm]
 
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index cae3ff6..3f036a9 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -94,6 +94,10 @@
     }
     this->PPDefinitions.insert(def);
   }
+
+  this->CompilerId = mf->GetSafeDefinition("CMAKE_Fortran_COMPILER_ID");
+  this->SModSep = mf->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
+  this->SModExt = mf->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
 }
 
 cmDependsFortran::~cmDependsFortran()
@@ -116,6 +120,11 @@
     return false;
   }
 
+  cmFortranCompiler fc;
+  fc.Id = this->CompilerId;
+  fc.SModSep = this->SModSep;
+  fc.SModExt = this->SModExt;
+
   bool okay = true;
   for (std::string const& src : sources) {
     // Get the information object for this source.
@@ -123,7 +132,7 @@
 
     // Create the parser object. The constructor takes info by reference,
     // so we may look into the resulting objects later.
-    cmFortranParser parser(this->IncludePath, this->PPDefinitions, info);
+    cmFortranParser parser(fc, this->IncludePath, this->PPDefinitions, info);
 
     // Push on the starting file.
     cmFortranParser_FilePush(&parser, src.c_str());
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index bf09904..0485115 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -77,6 +77,10 @@
   // The source file from which to start scanning.
   std::string SourceFile;
 
+  std::string CompilerId;
+  std::string SModSep;
+  std::string SModExt;
+
   std::set<std::string> PPDefinitions;
 
   // Internal implementation details.
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index 8d4c90b..0762340 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -128,15 +128,29 @@
   bool LastCharWasNewline;
 };
 
+struct cmFortranCompiler
+{
+  std::string Id;
+  std::string SModSep;
+  std::string SModExt;
+};
+
 struct cmFortranParser_s
 {
-  cmFortranParser_s(std::vector<std::string> includes,
+  cmFortranParser_s(cmFortranCompiler fc, std::vector<std::string> includes,
                     std::set<std::string> defines, cmFortranSourceInfo& info);
   ~cmFortranParser_s();
 
   bool FindIncludeFile(const char* dir, const char* includeName,
                        std::string& fileName);
 
+  std::string ModName(std::string const& mod_name) const;
+  std::string SModName(std::string const& mod_name,
+                       std::string const& sub_name) const;
+
+  // What compiler.
+  cmFortranCompiler Compiler;
+
   // The include file search path.
   std::vector<std::string> IncludePath;
 
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index 45481a4..18e3c10 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -43,10 +43,12 @@
   return false;
 }
 
-cmFortranParser_s::cmFortranParser_s(std::vector<std::string> includes,
+cmFortranParser_s::cmFortranParser_s(cmFortranCompiler fc,
+                                     std::vector<std::string> includes,
                                      std::set<std::string> defines,
                                      cmFortranSourceInfo& info)
-  : IncludePath(std::move(includes))
+  : Compiler(std::move(fc))
+  , IncludePath(std::move(includes))
   , PPDefinitions(std::move(defines))
   , Info(info)
 {
@@ -69,6 +71,17 @@
   cmFortran_yylex_destroy(this->Scanner);
 }
 
+std::string cmFortranParser_s::ModName(std::string const& mod_name) const
+{
+  return mod_name + ".mod";
+}
+
+std::string cmFortranParser_s::SModName(std::string const& mod_name,
+                                        std::string const& sub_name) const
+{
+  return mod_name + this->Compiler.SModSep + sub_name + this->Compiler.SModExt;
+}
+
 bool cmFortranParser_FilePush(cmFortranParser* parser, const char* fname)
 {
   // Open the new file and push it onto the stack.  Save the old
@@ -178,7 +191,7 @@
   // syntax:   "use module_name"
   // requires: "module_name.mod"
   std::string const& mod_name = cmSystemTools::LowerCase(module_name);
-  parser->Info.Requires.insert(mod_name + ".mod");
+  parser->Info.Requires.insert(parser->ModName(mod_name));
 }
 
 void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
@@ -242,7 +255,7 @@
     // syntax:   "module module_name"
     // provides: "module_name.mod"
     std::string const& mod_name = cmSystemTools::LowerCase(module_name);
-    parser->Info.Provides.insert(mod_name + ".mod");
+    parser->Info.Provides.insert(parser->ModName(mod_name));
   }
 }
 
@@ -265,8 +278,8 @@
 
   std::string const& mod_name = cmSystemTools::LowerCase(module_name);
   std::string const& sub_name = cmSystemTools::LowerCase(submodule_name);
-  parser->Info.Requires.insert(mod_name + ".mod");
-  parser->Info.Provides.insert(mod_name + "@" + sub_name + ".smod");
+  parser->Info.Requires.insert(parser->ModName(mod_name));
+  parser->Info.Provides.insert(parser->SModName(mod_name, sub_name));
 }
 
 void cmFortranParser_RuleSubmoduleNested(cmFortranParser* parser,
@@ -286,8 +299,8 @@
   std::string const& sub_name = cmSystemTools::LowerCase(submodule_name);
   std::string const& nest_name =
     cmSystemTools::LowerCase(nested_submodule_name);
-  parser->Info.Requires.insert(mod_name + "@" + sub_name + ".smod");
-  parser->Info.Provides.insert(mod_name + "@" + nest_name + ".smod");
+  parser->Info.Requires.insert(parser->SModName(mod_name, sub_name));
+  parser->Info.Provides.insert(parser->SModName(mod_name, nest_name));
 }
 
 void cmFortranParser_RuleDefine(cmFortranParser* parser, const char* macro)
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index ba1ace6..31bcacf 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1678,6 +1678,7 @@
     return 1;
   }
 
+  cmFortranCompiler fc;
   std::vector<std::string> includes;
   {
     Json::Value tdio;
@@ -1699,11 +1700,20 @@
         includes.push_back(tdi_include_dir.asString());
       }
     }
+
+    Json::Value const& tdi_compiler_id = tdi["compiler-id"];
+    fc.Id = tdi_compiler_id.asString();
+
+    Json::Value const& tdi_submodule_sep = tdi["submodule-sep"];
+    fc.SModSep = tdi_submodule_sep.asString();
+
+    Json::Value const& tdi_submodule_ext = tdi["submodule-ext"];
+    fc.SModExt = tdi_submodule_ext.asString();
   }
 
   cmFortranSourceInfo info;
   std::set<std::string> defines;
-  cmFortranParser parser(includes, defines, info);
+  cmFortranParser parser(fc, includes, defines, info);
   if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) {
     cmSystemTools::Error("-E cmake_ninja_depends failed to open ",
                          arg_pp.c_str());
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index d6f71d3..7eb4a03 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1808,6 +1808,17 @@
                       << "_COMPILER_ID \"" << cid << "\")\n";
     }
 
+    if (implicitLang.first == "Fortran") {
+      std::string smodSep =
+        this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
+      std::string smodExt =
+        this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
+      cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_SEP \"" << smodSep
+                      << "\")\n";
+      cmakefileStream << "set(CMAKE_Fortran_SUBMODULE_EXT \"" << smodExt
+                      << "\")\n";
+    }
+
     // Build a list of preprocessor definitions for the target.
     std::set<std::string> defines;
     this->GetTargetDefines(target, this->ConfigName, implicitLang.first,
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index b525dac..998729f 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1143,6 +1143,10 @@
       mod_dir = this->Makefile->GetCurrentBinaryDirectory();
     }
     tdi["module-dir"] = mod_dir;
+    tdi["submodule-sep"] =
+      this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP");
+    tdi["submodule-ext"] =
+      this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
   }
 
   tdi["dir-cur-bld"] = this->Makefile->GetCurrentBinaryDirectory();