From b0a6161190f8a85a5771fc96d5d745b0be2b07e5 Mon Sep 17 00:00:00 2001 From: Peter Hill Date: Fri, 24 Apr 2020 11:52:41 +0100 Subject: Fortran: Add Fortran_PREPROCESS property Issue: #18870 --- Auxiliary/vim/syntax/cmake.vim | 2 ++ Help/manual/cmake-properties.7.rst | 2 ++ Help/manual/cmake-variables.7.rst | 1 + Help/prop_sf/Fortran_FORMAT.rst | 10 +++--- Help/prop_sf/Fortran_PREPROCESS.rst | 12 +++++++ Help/prop_tgt/Fortran_PREPROCESS.rst | 18 ++++++++++ Help/release/dev/fortran-preprocess-property.rst | 6 ++++ Help/variable/CMAKE_Fortran_PREPROCESS.rst | 8 +++++ Modules/Compiler/Absoft-Fortran.cmake | 2 ++ Modules/Compiler/Cray-Fortran.cmake | 8 +++++ Modules/Compiler/Flang-Fortran.cmake | 3 ++ Modules/Compiler/G95-Fortran.cmake | 2 ++ Modules/Compiler/GNU-Fortran.cmake | 5 +++ Modules/Compiler/HP-Fortran.cmake | 3 ++ Modules/Compiler/Intel-Fortran.cmake | 2 ++ Modules/Compiler/NAG-Fortran.cmake | 1 + Modules/Compiler/PGI-Fortran.cmake | 1 + Modules/Compiler/PathScale-Fortran.cmake | 3 ++ Modules/Compiler/SunPro-Fortran.cmake | 2 ++ Modules/Compiler/XL-Fortran.cmake | 5 +++ Source/cmCommonTargetGenerator.cxx | 28 +++++++++++++++ Source/cmCommonTargetGenerator.h | 3 ++ Source/cmLocalVisualStudio7Generator.cxx | 27 ++++++++++++++ Source/cmMakefileTargetGenerator.cxx | 1 + Source/cmNinjaTargetGenerator.cxx | 1 + Source/cmOutputConverter.cxx | 11 ++++++ Source/cmOutputConverter.h | 8 +++++ Source/cmTarget.cxx | 1 + Tests/FortranOnly/CMakeLists.txt | 45 ++++++++++++++++++++++++ Tests/FortranOnly/no_preprocess_source_fpp.fpp | 3 ++ Tests/FortranOnly/no_preprocess_source_lower.f | 3 ++ Tests/FortranOnly/no_preprocess_source_upper.F | 3 ++ Tests/FortranOnly/no_preprocess_target_fpp.fpp | 3 ++ Tests/FortranOnly/no_preprocess_target_lower.f | 3 ++ Tests/FortranOnly/no_preprocess_target_upper.F | 3 ++ Tests/FortranOnly/preprocess2.f | 4 +++ Tests/FortranOnly/preprocess3.f | 4 +++ 37 files changed, 243 insertions(+), 4 deletions(-) create mode 100644 Help/prop_sf/Fortran_PREPROCESS.rst create mode 100644 Help/prop_tgt/Fortran_PREPROCESS.rst create mode 100644 Help/release/dev/fortran-preprocess-property.rst create mode 100644 Help/variable/CMAKE_Fortran_PREPROCESS.rst create mode 100644 Tests/FortranOnly/no_preprocess_source_fpp.fpp create mode 100644 Tests/FortranOnly/no_preprocess_source_lower.f create mode 100644 Tests/FortranOnly/no_preprocess_source_upper.F create mode 100644 Tests/FortranOnly/no_preprocess_target_fpp.fpp create mode 100644 Tests/FortranOnly/no_preprocess_target_lower.f create mode 100644 Tests/FortranOnly/no_preprocess_target_upper.F create mode 100644 Tests/FortranOnly/preprocess2.f create mode 100644 Tests/FortranOnly/preprocess3.f diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 0676f7e..2d63eb0 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -170,6 +170,7 @@ syn keyword cmakeProperty contained \ FRAMEWORK_VERSION \ Fortran_FORMAT \ Fortran_MODULE_DIRECTORY + \ Fortran_PREPROCESS \ GENERATED \ GENERATOR_FILE_NAME \ GENERATOR_IS_MULTI_CONFIG @@ -1019,6 +1020,7 @@ syn keyword cmakeVariable contained \ CMAKE_Fortran_MODULE_DIRECTORY \ CMAKE_Fortran_OUTPUT_EXTENSION \ CMAKE_Fortran_PLATFORM_ID + \ CMAKE_Fortran_PREPROCESS \ CMAKE_Fortran_SIMULATE_ID \ CMAKE_Fortran_SIMULATE_VERSION \ CMAKE_Fortran_SIZEOF_DATA_PTR diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 9031e9c..43bd08f 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -201,6 +201,7 @@ Properties on Targets /prop_tgt/FOLDER /prop_tgt/Fortran_FORMAT /prop_tgt/Fortran_MODULE_DIRECTORY + /prop_tgt/Fortran_PREPROCESS /prop_tgt/FRAMEWORK /prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG /prop_tgt/FRAMEWORK_VERSION @@ -465,6 +466,7 @@ Properties on Source Files /prop_sf/COMPILE_OPTIONS /prop_sf/EXTERNAL_OBJECT /prop_sf/Fortran_FORMAT + /prop_sf/Fortran_PREPROCESS /prop_sf/GENERATED /prop_sf/HEADER_FILE_ONLY /prop_sf/INCLUDE_DIRECTORIES diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 7d802e1..4ce8365 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -391,6 +391,7 @@ Variables that Control the Build /variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG /variable/CMAKE_Fortran_FORMAT /variable/CMAKE_Fortran_MODULE_DIRECTORY + /variable/CMAKE_Fortran_PREPROCESS /variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE /variable/CMAKE_GLOBAL_AUTOGEN_TARGET /variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME diff --git a/Help/prop_sf/Fortran_FORMAT.rst b/Help/prop_sf/Fortran_FORMAT.rst index 1cbbf48..ef33926 100644 --- a/Help/prop_sf/Fortran_FORMAT.rst +++ b/Help/prop_sf/Fortran_FORMAT.rst @@ -4,7 +4,9 @@ Fortran_FORMAT Set to ``FIXED`` or ``FREE`` to indicate the Fortran source layout. This property tells CMake whether a given Fortran source file uses -fixed-format or free-format. CMake will pass the corresponding format -flag to the compiler. Consider using the target-wide -:prop_tgt:`Fortran_FORMAT` property if all source files in a target -share the same format. +fixed-format or free-format. CMake will pass the corresponding format flag +to the compiler. Consider using the target-wide :prop_tgt:`Fortran_FORMAT` +property if all source files in a target share the same format. + +.. note:: For some compilers, ``NAG``, ``PGI`` and ``Solaris Studio``, + setting this to ``OFF`` will have no effect. diff --git a/Help/prop_sf/Fortran_PREPROCESS.rst b/Help/prop_sf/Fortran_PREPROCESS.rst new file mode 100644 index 0000000..92542d9 --- /dev/null +++ b/Help/prop_sf/Fortran_PREPROCESS.rst @@ -0,0 +1,12 @@ +Fortran_PREPROCESS +------------------ + +Control whether the Fortran source file should be unconditionally preprocessed. + +If unset or empty, rely on the compiler to determine whether the file +should be preprocessed. If explicitly set to ``OFF`` then the file +does not need to be preprocessed. If explicitly set to ``ON``, then +the file does need to be preprocessed as part of the compilation step. + +Consider using the target-wide :prop_tgt:`Fortran_PREPROCESS` property +if all source files in a target need to be preprocessed. diff --git a/Help/prop_tgt/Fortran_PREPROCESS.rst b/Help/prop_tgt/Fortran_PREPROCESS.rst new file mode 100644 index 0000000..069d04a --- /dev/null +++ b/Help/prop_tgt/Fortran_PREPROCESS.rst @@ -0,0 +1,18 @@ +Fortran_PREPROCESS +------------------ + +Control whether the Fortran source file should be unconditionally +preprocessed. + +If unset or empty, rely on the compiler to determine whether the file +should be preprocessed. If explicitly set to ``OFF`` then the file does not +need to be preprocessed. If explicitly set to ``ON``, then the file does +need to be preprocessed as part of the compilation step. + +Use the source-specific :prop_sf:`Fortran_PREPROCESS` property if a single +file needs to be preprocessed. If the variable +:variable:`CMAKE_Fortran_PREPROCESS` is set when a target is created its +value is used to initialize this property. + +.. note:: For some compilers, ``NAG``, ``PGI`` and ``Solaris Studio``, + setting this to ``OFF`` will have no effect. diff --git a/Help/release/dev/fortran-preprocess-property.rst b/Help/release/dev/fortran-preprocess-property.rst new file mode 100644 index 0000000..d18e7b8 --- /dev/null +++ b/Help/release/dev/fortran-preprocess-property.rst @@ -0,0 +1,6 @@ +fortran-preprocess-property +--------------------------- + +* The :prop_tgt:`Fortran_PREPROCESS` target property and + :prop_sf:`Fortran_PREPROCESS` source-file property were added to + control preprocessing of Fortran source files. diff --git a/Help/variable/CMAKE_Fortran_PREPROCESS.rst b/Help/variable/CMAKE_Fortran_PREPROCESS.rst new file mode 100644 index 0000000..74b2d8b --- /dev/null +++ b/Help/variable/CMAKE_Fortran_PREPROCESS.rst @@ -0,0 +1,8 @@ +CMAKE_Fortran_PREPROCESS +------------------------ + +Default value for :prop_tgt:`Fortran_PREPROCESS` of targets. + +This variable is used to initialize the :prop_tgt:`Fortran_PREPROCESS` +property on all the targets. See that target property for additional +information. diff --git a/Modules/Compiler/Absoft-Fortran.cmake b/Modules/Compiler/Absoft-Fortran.cmake index 76502dc..8724f85 100644 --- a/Modules/Compiler/Absoft-Fortran.cmake +++ b/Modules/Compiler/Absoft-Fortran.cmake @@ -9,3 +9,5 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree") set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-X") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-no-cpp") diff --git a/Modules/Compiler/Cray-Fortran.cmake b/Modules/Compiler/Cray-Fortran.cmake index ccb7c2e..696ae76 100644 --- a/Modules/Compiler/Cray-Fortran.cmake +++ b/Modules/Compiler/Cray-Fortran.cmake @@ -11,3 +11,11 @@ set(CMAKE_Fortran_MODDIR_FLAG -J) set(CMAKE_Fortran_MODDIR_DEFAULT .) set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-f fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-f free") + +if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 8.5) + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-eT") + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-dT") +else() + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-eZ") + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-dZ") +endif() diff --git a/Modules/Compiler/Flang-Fortran.cmake b/Modules/Compiler/Flang-Fortran.cmake index f0e61d8..de0484e 100644 --- a/Modules/Compiler/Flang-Fortran.cmake +++ b/Modules/Compiler/Flang-Fortran.cmake @@ -11,3 +11,6 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") set(CMAKE_Fortran_MODDIR_FLAG "-J") + +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp") diff --git a/Modules/Compiler/G95-Fortran.cmake b/Modules/Compiler/G95-Fortran.cmake index 03b7e08..5dba04e 100644 --- a/Modules/Compiler/G95-Fortran.cmake +++ b/Modules/Compiler/G95-Fortran.cmake @@ -9,3 +9,5 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,") set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-no-cpp") diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake index 6413769..5dfb03e 100644 --- a/Modules/Compiler/GNU-Fortran.cmake +++ b/Modules/Compiler/GNU-Fortran.cmake @@ -10,6 +10,11 @@ set(CMAKE_Fortran_PREPROCESS_SOURCE set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") +if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.4) + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp") + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp") +endif() + set(CMAKE_Fortran_POSTPROCESS_FLAG "-fpreprocessed") # No -DNDEBUG for Fortran. diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake index 63a0331..d3e2a30 100644 --- a/Modules/Compiler/HP-Fortran.cmake +++ b/Modules/Compiler/HP-Fortran.cmake @@ -7,3 +7,6 @@ set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE " set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,") set(CMAKE_Fortran_LINKER_WRAPPER_FLAG ",") + +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "+cpp=yes") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "+cpp=no") diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake index 156b533..71f25f4 100644 --- a/Modules/Compiler/Intel-Fortran.cmake +++ b/Modules/Compiler/Intel-Fortran.cmake @@ -15,3 +15,5 @@ set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE " -fpp -E > ") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nofpp") diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake index 2111c65..ffce97e 100644 --- a/Modules/Compiler/NAG-Fortran.cmake +++ b/Modules/Compiler/NAG-Fortran.cmake @@ -37,3 +37,4 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-PIC") set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "-PIC") set(CMAKE_Fortran_RESPONSE_FILE_LINK_FLAG "-Wl,@") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp") diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake index 3daf798..ff87577 100644 --- a/Modules/Compiler/PGI-Fortran.cmake +++ b/Modules/Compiler/PGI-Fortran.cmake @@ -6,6 +6,7 @@ set(CMAKE_Fortran_SUBMODULE_EXT ".mod") set(CMAKE_Fortran_PREPROCESS_SOURCE " -Mpreprocess -E > ") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-Mpreprocess") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-Mnofreeform") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform") diff --git a/Modules/Compiler/PathScale-Fortran.cmake b/Modules/Compiler/PathScale-Fortran.cmake index d903621..891d93e 100644 --- a/Modules/Compiler/PathScale-Fortran.cmake +++ b/Modules/Compiler/PathScale-Fortran.cmake @@ -4,3 +4,6 @@ __compiler_pathscale(Fortran) set(CMAKE_Fortran_MODDIR_FLAG "-module ") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixedform") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-freeform") + +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp") +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index 0c93c94..0ba5015 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -30,3 +30,5 @@ set(CMAKE_Fortran_PREPROCESS_SOURCE set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE " -F -fpp -o ") set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE " -S -o ") + +set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp") diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake index e01ec8e..cc15e65 100644 --- a/Modules/Compiler/XL-Fortran.cmake +++ b/Modules/Compiler/XL-Fortran.cmake @@ -23,3 +23,8 @@ set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) set(CMAKE_Fortran_PREPROCESS_SOURCE " -qpreprocess -qnoobject -qsuppress=1517-020 -tF -B \"${CMAKE_CURRENT_LIST_DIR}/XL-Fortran/\" -WF,--cpp,\"${CMAKE_Fortran_XL_CPP}\",--out, " ) + +if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 15.1.6) + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-qpreprocess") + set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-qnopreprocess") +endif() diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 5414409..32a33ee 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -98,6 +98,34 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags( } } +void cmCommonTargetGenerator::AppendFortranPreprocessFlags( + std::string& flags, cmSourceFile const& source) +{ + const std::string srcpp = source.GetSafeProperty("Fortran_PREPROCESS"); + cmOutputConverter::FortranPreprocess preprocess = + cmOutputConverter::GetFortranPreprocess(srcpp); + if (preprocess == cmOutputConverter::FortranPreprocess::Unset) { + std::string const& tgtpp = + this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS"); + preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp); + } + const char* var = nullptr; + switch (preprocess) { + case cmOutputConverter::FortranPreprocess::Needed: + var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON"; + break; + case cmOutputConverter::FortranPreprocess::NotNeeded: + var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF"; + break; + default: + break; + } + if (var) { + this->LocalCommonGenerator->AppendCompileOptions( + flags, this->Makefile->GetSafeDefinition(var)); + } +} + std::string cmCommonTargetGenerator::GetFlags(const std::string& l, const std::string& config, const std::string& arch) diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h index 78cedf5..c3c3a3a 100644 --- a/Source/cmCommonTargetGenerator.h +++ b/Source/cmCommonTargetGenerator.h @@ -45,6 +45,9 @@ protected: void AppendFortranFormatFlags(std::string& flags, cmSourceFile const& source); + void AppendFortranPreprocessFlags(std::string& flags, + cmSourceFile const& source); + virtual void AddIncludeFlags(std::string& flags, std::string const& lang, const std::string& config) = 0; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index e18fac3..f7a0c5a 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -284,6 +284,7 @@ void cmLocalVisualStudio7Generator::WriteConfigurations( } cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = { { "Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0 }, + { "Preprocess", "nofpp", "Run Preprocessor on files", "preprocessNo", 0 }, { "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 }, { "SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0 }, { "SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0 }, @@ -682,6 +683,18 @@ void cmLocalVisualStudio7Generator::WriteConfiguration( default: break; } + + switch (cmOutputConverter::GetFortranPreprocess( + target->GetSafeProperty("Fortran_PREPROCESS"))) { + case cmOutputConverter::FortranPreprocess::Needed: + flags += " -fpp"; + break; + case cmOutputConverter::FortranPreprocess::NotNeeded: + flags += " -nofpp"; + break; + default: + break; + } } // Get preprocessor definitions for this directory. @@ -1474,6 +1487,20 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo( } if (lg->FortranProject) { + switch (cmOutputConverter::GetFortranPreprocess( + sf.GetSafeProperty("Fortran_PREPROCESS"))) { + case cmOutputConverter::FortranPreprocess::Needed: + fc.CompileFlags = cmStrCat("-fpp ", fc.CompileFlags); + needfc = true; + break; + case cmOutputConverter::FortranPreprocess::NotNeeded: + fc.CompileFlags = cmStrCat("-nofpp ", fc.CompileFlags); + needfc = true; + break; + default: + break; + } + switch (cmOutputConverter::GetFortranFormat( sf.GetSafeProperty("Fortran_FORMAT"))) { case cmOutputConverter::FortranFormatFixed: diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 5f0cfcf..dcd121c 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -541,6 +541,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // Add Fortran format flags. if (lang == "Fortran") { this->AppendFortranFormatFlags(flags, source); + this->AppendFortranPreprocessFlags(flags, source); } // Add flags from source file properties. diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 0606484..b58434f 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -183,6 +183,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject( // Add Fortran format flags. if (language == "Fortran") { this->AppendFortranFormatFlags(flags, *source); + this->AppendFortranPreprocessFlags(flags, *source); } // Add source file specific flags. diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx index dc324cc..359e9f5 100644 --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -170,6 +170,17 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat( return format; } +cmOutputConverter::FortranPreprocess cmOutputConverter::GetFortranPreprocess( + cm::string_view value) +{ + if (value.empty()) { + return FortranPreprocess::Unset; + } + + return cmIsOn(value) ? FortranPreprocess::Needed + : FortranPreprocess::NotNeeded; +} + void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell) { this->LinkScriptShell = linkScriptShell; diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h index 28582df..a8b4528 100644 --- a/Source/cmOutputConverter.h +++ b/Source/cmOutputConverter.h @@ -95,6 +95,14 @@ public: }; static FortranFormat GetFortranFormat(cm::string_view value); + enum class FortranPreprocess + { + Unset, + NotNeeded, + Needed + }; + static FortranPreprocess GetFortranPreprocess(cm::string_view value); + private: cmState* GetState() const; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index a776398..16d7b6f 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -307,6 +307,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("Fortran_FORMAT"); initProp("Fortran_MODULE_DIRECTORY"); initProp("Fortran_COMPILER_LAUNCHER"); + initProp("Fortran_PREPROCESS"); initProp("GNUtoMS"); initProp("OSX_ARCHITECTURES"); initProp("IOS_INSTALL_COMBINED"); diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index 4327c2f..59f139b 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -116,3 +116,48 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") set_property(TARGET IntelIfDef PROPERTY Fortran_FORMAT FIXED) target_compile_definitions(IntelIfDef PRIVATE SOME_DEF) endif() + +# Skip these tests if compiler/version doesn't have preprocessing flags +if((CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.4) + OR (CMAKE_Fortran_COMPILER_ID STREQUAL "XL" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 15.1.6)) + set(test_pp_flags 0) +else() + set(test_pp_flags 1) +endif() + +if(test_pp_flags) + # Test that we can always preprocess a target + add_executable(preprocess_target preprocess2.f) + set_property(TARGET preprocess_target PROPERTY Fortran_PREPROCESS ON) + + # Test that we can preprocess a single source file + add_executable(preprocess_source preprocess3.f) + set_property(SOURCE preprocess3.f PROPERTY Fortran_PREPROCESS ON) +endif() + +if(NOT CMAKE_GENERATOR MATCHES "Ninja") + # Test that neither the compiler nor CMake performs unnecessary preprocessing. + add_library(no_preprocess_target_lower STATIC no_preprocess_target_lower.f) + target_compile_options(no_preprocess_target_lower PRIVATE -DINTEGER=nonsense) + set_property(TARGET no_preprocess_target_lower PROPERTY Fortran_PREPROCESS OFF) + add_library(no_preprocess_source_lower STATIC no_preprocess_source_lower.f) + target_compile_options(no_preprocess_source_lower PRIVATE -DINTEGER=nonsense) + set_property(SOURCE no_preprocess_source_lower.f PROPERTY Fortran_PREPROCESS OFF) + + # Test that we can explicitly not preprocess a target or source. + # This will not work on certain compilers due to either missing a + # "don't preprocess" flag, or due to choice of file extension. + if(test_pp_flags AND NOT CMAKE_Fortran_COMPILER_ID MATCHES "(Flang|NAG|PGI|SunPro|XL)") + add_library(no_preprocess_target STATIC no_preprocess_target_upper.F) + target_compile_options(no_preprocess_target PRIVATE -DINTEGER=nonsense) + add_library(no_preprocess_source STATIC no_preprocess_source_upper.F) + target_compile_options(no_preprocess_source PRIVATE -DINTEGER=nonsense) + if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "Cray" + AND NOT "${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "Intel;MSVC") + target_sources(no_preprocess_target PRIVATE no_preprocess_target_fpp.fpp) + target_sources(no_preprocess_source PRIVATE no_preprocess_source_fpp.fpp) + endif() + set_property(TARGET no_preprocess_target PROPERTY Fortran_PREPROCESS OFF) + set_property(SOURCE no_preprocess_source_upper.F no_preprocess_source_fpp.fpp PROPERTY Fortran_PREPROCESS OFF) + endif() +endif() diff --git a/Tests/FortranOnly/no_preprocess_source_fpp.fpp b/Tests/FortranOnly/no_preprocess_source_fpp.fpp new file mode 100644 index 0000000..8e48902 --- /dev/null +++ b/Tests/FortranOnly/no_preprocess_source_fpp.fpp @@ -0,0 +1,3 @@ + SUBROUTINE NOPREPROCESS_SOURCE_FPP + INTEGER F + END diff --git a/Tests/FortranOnly/no_preprocess_source_lower.f b/Tests/FortranOnly/no_preprocess_source_lower.f new file mode 100644 index 0000000..3b08782 --- /dev/null +++ b/Tests/FortranOnly/no_preprocess_source_lower.f @@ -0,0 +1,3 @@ + SUBROUTINE NOPREPROCESS_SOURCE_LOWER + INTEGER F + END diff --git a/Tests/FortranOnly/no_preprocess_source_upper.F b/Tests/FortranOnly/no_preprocess_source_upper.F new file mode 100644 index 0000000..02485c9 --- /dev/null +++ b/Tests/FortranOnly/no_preprocess_source_upper.F @@ -0,0 +1,3 @@ + SUBROUTINE NOPREPROCESS_SOURCE_UPPER + INTEGER F + END diff --git a/Tests/FortranOnly/no_preprocess_target_fpp.fpp b/Tests/FortranOnly/no_preprocess_target_fpp.fpp new file mode 100644 index 0000000..f9e6e3b --- /dev/null +++ b/Tests/FortranOnly/no_preprocess_target_fpp.fpp @@ -0,0 +1,3 @@ + SUBROUTINE NOPREPROCESS_TARGET_FPP + INTEGER F + END diff --git a/Tests/FortranOnly/no_preprocess_target_lower.f b/Tests/FortranOnly/no_preprocess_target_lower.f new file mode 100644 index 0000000..ea23a70 --- /dev/null +++ b/Tests/FortranOnly/no_preprocess_target_lower.f @@ -0,0 +1,3 @@ + SUBROUTINE NOPREPROCESS_TARGET_LOWER + INTEGER F + END diff --git a/Tests/FortranOnly/no_preprocess_target_upper.F b/Tests/FortranOnly/no_preprocess_target_upper.F new file mode 100644 index 0000000..34ee04d --- /dev/null +++ b/Tests/FortranOnly/no_preprocess_target_upper.F @@ -0,0 +1,3 @@ + SUBROUTINE NOPREPROCESS_TARGET_UPPER + INTEGER F + END diff --git a/Tests/FortranOnly/preprocess2.f b/Tests/FortranOnly/preprocess2.f new file mode 100644 index 0000000..6595d62 --- /dev/null +++ b/Tests/FortranOnly/preprocess2.f @@ -0,0 +1,4 @@ +#define int INTEGER + PROGRAM PREPRO + int f + END diff --git a/Tests/FortranOnly/preprocess3.f b/Tests/FortranOnly/preprocess3.f new file mode 100644 index 0000000..6595d62 --- /dev/null +++ b/Tests/FortranOnly/preprocess3.f @@ -0,0 +1,4 @@ +#define int INTEGER + PROGRAM PREPRO + int f + END -- cgit v0.12