summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsuru Fernando <isuruf@gmail.com>2020-11-19 11:33:23 -0600
committerBrad King <brad.king@kitware.com>2021-06-24 08:39:47 -0400
commitfe3f846e1b88341529686ee7dd334b01fe9e705e (patch)
tree95a4facd2432b9eb74d4039cd467d364d3a0ab2e
parent66488d4eb31d372d8e06ce78e5f49a7cc43974ee (diff)
downloadcmake-fe3f846e1b88341529686ee7dd334b01fe9e705e.tar.gz
Makefiles: Add support for building Fortran intrinsics
Fixes: #21463
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst14
-rw-r--r--Source/LexerParser/cmFortranParser.cxx78
-rw-r--r--Source/LexerParser/cmFortranParser.y4
-rw-r--r--Source/cmDependsFortran.cxx17
-rw-r--r--Source/cmDependsFortran.h3
-rw-r--r--Source/cmFortranParser.h5
-rw-r--r--Source/cmFortranParserImpl.cxx13
-rw-r--r--Source/cmGeneratorTarget.cxx8
-rw-r--r--Source/cmGeneratorTarget.h1
-rw-r--r--Source/cmMakefileTargetGenerator.cxx7
11 files changed, 110 insertions, 41 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 5f18a82475..4212913a96 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -202,6 +202,7 @@ Properties on Targets
/prop_tgt/EXPORT_NAME
/prop_tgt/EXPORT_PROPERTIES
/prop_tgt/FOLDER
+ /prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES
/prop_tgt/Fortran_FORMAT
/prop_tgt/Fortran_MODULE_DIRECTORY
/prop_tgt/Fortran_PREPROCESS
diff --git a/Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst b/Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst
new file mode 100644
index 0000000000..518bca7268
--- /dev/null
+++ b/Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst
@@ -0,0 +1,14 @@
+Fortran_BUILDING_INSTRINSIC_MODULES
+-----------------------------------
+
+Instructs the CMake Fortran preprocessor that the target is building
+Fortran intrinsics for building a Fortran compiler.
+
+This property is off by default and should be turned only on projects
+that build a Fortran compiler. It should not be turned on for projects
+that use a Fortran compiler.
+
+Turning this property on will correctly add dependencies for building
+Fortran intrinsic modules whereas turning the property off will ignore
+Fortran intrinsic modules in the dependency graph as they are supplied
+by the compiler itself.
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 3f3dddeb4e..50e97529bf 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -600,12 +600,12 @@ static const yytype_int8 yytranslate[] =
static const yytype_uint8 yyrline[] =
{
0, 101, 101, 101, 104, 108, 113, 122, 128, 135,
- 140, 144, 149, 157, 162, 167, 172, 177, 182, 187,
- 192, 197, 201, 205, 209, 213, 214, 219, 219, 219,
- 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
- 225, 225, 226, 226, 227, 227, 228, 228, 231, 232,
- 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
- 243, 244, 245, 246, 247
+ 140, 144, 149, 161, 166, 171, 176, 181, 186, 191,
+ 196, 201, 205, 209, 213, 217, 218, 223, 223, 223,
+ 224, 224, 225, 225, 226, 226, 227, 227, 228, 228,
+ 229, 229, 230, 230, 231, 231, 232, 232, 235, 236,
+ 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 249, 250, 251
};
#endif
@@ -1747,142 +1747,146 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
}
+ if (cmsysString_strcasecmp((yyvsp[-4].string), "intrinsic") == 0) {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUseIntrinsic(parser, (yyvsp[-2].string));
+ }
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1754 "cmFortranParser.cxx"
+#line 1758 "cmFortranParser.cxx"
break;
case 13: /* stmt: INCLUDE STRING other EOSTMT */
-#line 157 "cmFortranParser.y"
+#line 161 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1764 "cmFortranParser.cxx"
+#line 1768 "cmFortranParser.cxx"
break;
case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT */
-#line 162 "cmFortranParser.y"
+#line 166 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1774 "cmFortranParser.cxx"
+#line 1778 "cmFortranParser.cxx"
break;
case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT */
-#line 167 "cmFortranParser.y"
+#line 171 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1784 "cmFortranParser.cxx"
+#line 1788 "cmFortranParser.cxx"
break;
case 16: /* stmt: include STRING other EOSTMT */
-#line 172 "cmFortranParser.y"
+#line 176 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1794 "cmFortranParser.cxx"
+#line 1798 "cmFortranParser.cxx"
break;
case 17: /* stmt: define WORD other EOSTMT */
-#line 177 "cmFortranParser.y"
+#line 181 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1804 "cmFortranParser.cxx"
+#line 1808 "cmFortranParser.cxx"
break;
case 18: /* stmt: undef WORD other EOSTMT */
-#line 182 "cmFortranParser.y"
+#line 186 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1814 "cmFortranParser.cxx"
+#line 1818 "cmFortranParser.cxx"
break;
case 19: /* stmt: ifdef WORD other EOSTMT */
-#line 187 "cmFortranParser.y"
+#line 191 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1824 "cmFortranParser.cxx"
+#line 1828 "cmFortranParser.cxx"
break;
case 20: /* stmt: ifndef WORD other EOSTMT */
-#line 192 "cmFortranParser.y"
+#line 196 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1834 "cmFortranParser.cxx"
+#line 1838 "cmFortranParser.cxx"
break;
case 21: /* stmt: if other EOSTMT */
-#line 197 "cmFortranParser.y"
+#line 201 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1843 "cmFortranParser.cxx"
+#line 1847 "cmFortranParser.cxx"
break;
case 22: /* stmt: elif other EOSTMT */
-#line 201 "cmFortranParser.y"
+#line 205 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1852 "cmFortranParser.cxx"
+#line 1856 "cmFortranParser.cxx"
break;
case 23: /* stmt: else other EOSTMT */
-#line 205 "cmFortranParser.y"
+#line 209 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1861 "cmFortranParser.cxx"
+#line 1865 "cmFortranParser.cxx"
break;
case 24: /* stmt: endif other EOSTMT */
-#line 209 "cmFortranParser.y"
+#line 213 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1870 "cmFortranParser.cxx"
+#line 1874 "cmFortranParser.cxx"
break;
case 48: /* misc_code: WORD */
-#line 231 "cmFortranParser.y"
+#line 235 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1876 "cmFortranParser.cxx"
+#line 1880 "cmFortranParser.cxx"
break;
case 55: /* misc_code: STRING */
-#line 238 "cmFortranParser.y"
+#line 242 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1882 "cmFortranParser.cxx"
+#line 1886 "cmFortranParser.cxx"
break;
-#line 1886 "cmFortranParser.cxx"
+#line 1890 "cmFortranParser.cxx"
default: break;
}
@@ -2107,6 +2111,6 @@ yyreturn:
return yyresult;
}
-#line 250 "cmFortranParser.y"
+#line 254 "cmFortranParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index a3e1c24b12..8ef19035c6 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -151,6 +151,10 @@ stmt:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, $5);
}
+ if (cmsysString_strcasecmp($3, "intrinsic") == 0) {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUseIntrinsic(parser, $5);
+ }
free($3);
free($5);
}
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index bca26b9caa..6024cf6240 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -163,12 +163,17 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
mod_dir = this->LocalGenerator->GetCurrentBinaryDirectory();
}
+ bool building_intrinsics =
+ !mf->GetSafeDefinition("CMAKE_Fortran_TARGET_BUILDING_INSTRINSIC_MODULES")
+ .empty();
+
// Actually write dependencies to the streams.
using ObjectInfoMap = cmDependsFortranInternals::ObjectInfoMap;
ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
for (auto const& i : objInfo) {
if (!this->WriteDependenciesReal(i.first, i.second, mod_dir, stamp_dir,
- makeDepends, internalDepends)) {
+ makeDepends, internalDepends,
+ building_intrinsics)) {
return false;
}
}
@@ -307,7 +312,8 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::string const& mod_dir,
std::string const& stamp_dir,
std::ostream& makeDepends,
- std::ostream& internalDepends)
+ std::ostream& internalDepends,
+ bool buildingIntrinsics)
{
// Get the source file for this object.
std::string const& src = info.Source;
@@ -339,8 +345,13 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
makeDepends << '\n';
}
+ std::set<std::string> req = info.Requires;
+ if (buildingIntrinsics) {
+ req.insert(info.Intrinsics.begin(), info.Intrinsics.end());
+ }
+
// Write module requirements to the output stream.
- for (std::string const& i : info.Requires) {
+ for (std::string const& i : req) {
// Require only modules not provided in the same source.
if (info.Provides.find(i) != info.Provides.cend()) {
continue;
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 0d407bc3bc..a74db91f3d 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -72,7 +72,8 @@ protected:
std::string const& mod_dir,
std::string const& stamp_dir,
std::ostream& makeDepends,
- std::ostream& internalDepends);
+ std::ostream& internalDepends,
+ bool buildingIntrinsics);
// The source file from which to start scanning.
std::string SourceFile;
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index 1b14d17772..70fe5374ce 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -40,6 +40,8 @@ int cmFortranParser_GetOldStartcond(cmFortranParser* parser);
/* Callbacks for parser. */
void cmFortranParser_Error(cmFortranParser* parser, const char* message);
void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name);
+void cmFortranParser_RuleUseIntrinsic(cmFortranParser* parser,
+ const char* module_name);
void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
const char* filename);
void cmFortranParser_RuleInclude(cmFortranParser* parser, const char* name);
@@ -99,6 +101,9 @@ public:
std::set<std::string> Provides;
std::set<std::string> Requires;
+ // Set of intrinsic modules.
+ std::set<std::string> Intrinsics;
+
// Set of files included in the translation unit.
std::set<std::string> Includes;
};
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index 054a2a93e6..efcc5bb2e6 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -197,6 +197,19 @@ void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name)
parser->Info.Requires.insert(parser->ModName(mod_name));
}
+void cmFortranParser_RuleUseIntrinsic(cmFortranParser* parser,
+ const char* module_name)
+{
+ if (parser->InPPFalseBranch) {
+ return;
+ }
+
+ // syntax: "use, intrinsic:: module_name"
+ // requires: "module_name.mod"
+ std::string const& mod_name = cmSystemTools::LowerCase(module_name);
+ parser->Info.Intrinsics.insert(parser->ModName(mod_name));
+}
+
void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
const char* filename)
{
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index f268c6c3e6..34797c5c53 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -6175,6 +6175,14 @@ std::string cmGeneratorTarget::GetFortranModuleDirectory(
return this->FortranModuleDirectory;
}
+bool cmGeneratorTarget::IsFortranBuildingInstrinsicModules() const
+{
+ if (cmProp prop = this->GetProperty("Fortran_BUILDING_INSTRINSIC_MODULES")) {
+ return cmIsOn(*prop);
+ }
+ return false;
+}
+
std::string cmGeneratorTarget::CreateFortranModuleDirectory(
std::string const& working_dir) const
{
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index ed66fb1a81..0619279cfc 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -832,6 +832,7 @@ public:
std::string const& config) const;
std::string GetFortranModuleDirectory(std::string const& working_dir) const;
+ bool IsFortranBuildingInstrinsicModules() const;
const std::string& GetSourcesProperty() const;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 6d8376c678..d6145f8566 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1380,6 +1380,13 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "set(CMAKE_Fortran_TARGET_MODULE_DIR \""
<< this->GeneratorTarget->GetFortranModuleDirectory(working_dir)
<< "\")\n";
+
+ if (this->GeneratorTarget->IsFortranBuildingInstrinsicModules()) {
+ *this->InfoFileStream
+ << "\n"
+ << "# Fortran compiler is building intrinsic modules.\n"
+ << "set(CMAKE_Fortran_TARGET_BUILDING_INSTRINSIC_MODULES ON) \n";
+ }
/* clang-format on */
// and now write the rule to use it