diff options
-rw-r--r-- | Help/manual/cmake-properties.7.rst | 1 | ||||
-rw-r--r-- | Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst | 14 | ||||
-rw-r--r-- | Source/LexerParser/cmFortranParser.cxx | 78 | ||||
-rw-r--r-- | Source/LexerParser/cmFortranParser.y | 4 | ||||
-rw-r--r-- | Source/cmDependsFortran.cxx | 17 | ||||
-rw-r--r-- | Source/cmDependsFortran.h | 3 | ||||
-rw-r--r-- | Source/cmFortranParser.h | 5 | ||||
-rw-r--r-- | Source/cmFortranParserImpl.cxx | 13 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 8 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 1 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 7 |
11 files changed, 110 insertions, 41 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 5f18a82..4212913 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 0000000..518bca7 --- /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 3f3ddde..50e9752 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 a3e1c24..8ef1903 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 bca26b9..6024cf6 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 0d407bc..a74db91 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 1b14d17..70fe537 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 054a2a9..efcc5bb 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 f268c6c..34797c5 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 ed66fb1..0619279 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 6d8376c..d6145f8 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 |