From 5c0c635a0947aa44a0e3edf65b73c61d9abced2d Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 31 Aug 2011 10:24:43 -0400 Subject: [PATCH] Fortran: Add support for free- and fixed-form flags Define a "Fortran_FORMAT" target and source file property. Initialize the target property from a "CMAKE_Fortran_FORMAT" variable. Interpret values "FIXED" and "FREE" to indicate the source file format. Append corresponding flags to the compiler command line. --- Modules/Compiler/Absoft-Fortran.cmake | 2 ++ Modules/Compiler/Cray-Fortran.cmake | 2 ++ Modules/Compiler/G95-Fortran.cmake | 2 ++ Modules/Compiler/GNU-Fortran.cmake | 3 ++ Modules/Compiler/HP-Fortran.cmake | 2 ++ Modules/Compiler/Intel-Fortran.cmake | 2 ++ Modules/Compiler/MIPSpro-Fortran.cmake | 2 ++ Modules/Compiler/NAG-Fortran.cmake | 2 ++ Modules/Compiler/PGI-Fortran.cmake | 3 ++ Modules/Compiler/PathScale-Fortran.cmake | 2 ++ Modules/Compiler/SunPro-Fortran.cmake | 2 ++ Modules/Compiler/XL-Fortran.cmake | 3 ++ Source/cmDocumentVariables.cxx | 9 ++++++ Source/cmLocalGenerator.cxx | 25 +++++++++++++++++ Source/cmLocalGenerator.h | 8 ++++++ Source/cmLocalVisualStudio7Generator.cxx | 25 +++++++++++++++++ Source/cmMakefileTargetGenerator.cxx | 35 ++++++++++++++++++++++++ Source/cmMakefileTargetGenerator.h | 2 ++ Source/cmSourceFile.cxx | 9 ++++++ Source/cmTarget.cxx | 12 ++++++++ Tests/Fortran/CMakeLists.txt | 2 ++ Tests/FortranOnly/CMakeLists.txt | 3 ++ Tests/FortranOnly/world.f | 9 +++--- 23 files changed, 161 insertions(+), 5 deletions(-) diff --git a/Modules/Compiler/Absoft-Fortran.cmake b/Modules/Compiler/Absoft-Fortran.cmake index bb7d3dc71..1bb7b1f82 100644 --- a/Modules/Compiler/Absoft-Fortran.cmake +++ b/Modules/Compiler/Absoft-Fortran.cmake @@ -6,3 +6,5 @@ SET(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-O2 -g") SET(CMAKE_Fortran_MODDIR_FLAG "-YMOD_OUT_DIR=") SET(CMAKE_Fortran_MODPATH_FLAG "-p") SET(CMAKE_Fortran_VERBOSE_FLAG "-v") +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree") diff --git a/Modules/Compiler/Cray-Fortran.cmake b/Modules/Compiler/Cray-Fortran.cmake index 4f45176d2..5d81bb02c 100644 --- a/Modules/Compiler/Cray-Fortran.cmake +++ b/Modules/Compiler/Cray-Fortran.cmake @@ -2,3 +2,5 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_MODOUT_FLAG -em) 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") diff --git a/Modules/Compiler/G95-Fortran.cmake b/Modules/Compiler/G95-Fortran.cmake index cbd466118..fd84848b4 100644 --- a/Modules/Compiler/G95-Fortran.cmake +++ b/Modules/Compiler/G95-Fortran.cmake @@ -5,3 +5,5 @@ set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3") set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-O2 -g") set(CMAKE_Fortran_MODDIR_FLAG "-fmod=") set(CMAKE_Fortran_VERBOSE_FLAG "-v") +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake index 6e0f5f3d5..c710e8698 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_FORMAT_FIXED_FLAG "-ffixed-form") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") + # No -DNDEBUG for Fortran. SET(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os") SET(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3") diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake index 7f7c1289a..04fb96ea4 100644 --- a/Modules/Compiler/HP-Fortran.cmake +++ b/Modules/Compiler/HP-Fortran.cmake @@ -1 +1,3 @@ SET(CMAKE_Fortran_VERBOSE_FLAG "-v") +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "+source=fixed") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free") diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake index f38b32e0e..467abdcf5 100644 --- a/Modules/Compiler/Intel-Fortran.cmake +++ b/Modules/Compiler/Intel-Fortran.cmake @@ -5,3 +5,5 @@ SET(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3") SET(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-O2 -g") SET(CMAKE_Fortran_MODDIR_FLAG "-module ") SET(CMAKE_Fortran_VERBOSE_FLAG "-v") +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") diff --git a/Modules/Compiler/MIPSpro-Fortran.cmake b/Modules/Compiler/MIPSpro-Fortran.cmake index 7f7c1289a..9220d3bf0 100644 --- a/Modules/Compiler/MIPSpro-Fortran.cmake +++ b/Modules/Compiler/MIPSpro-Fortran.cmake @@ -1 +1,3 @@ SET(CMAKE_Fortran_VERBOSE_FLAG "-v") +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixedform") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-freeform") diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake index b68c47994..9a89746b5 100644 --- a/Modules/Compiler/NAG-Fortran.cmake +++ b/Modules/Compiler/NAG-Fortran.cmake @@ -30,3 +30,5 @@ endif() set(CMAKE_Fortran_MODDIR_FLAG "-mdir ") set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-PIC") +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 1d2631552..aebc7b1c2 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_FORMAT_FIXED_FLAG "-Mnofreeform") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform") + SET(CMAKE_Fortran_FLAGS_INIT "${CMAKE_Fortran_FLAGS_INIT} -Mpreprocess -Kieee") SET(CMAKE_Fortran_FLAGS_DEBUG_INIT "${CMAKE_Fortran_FLAGS_DEBUG_INIT} -Mbounds") diff --git a/Modules/Compiler/PathScale-Fortran.cmake b/Modules/Compiler/PathScale-Fortran.cmake index 20c9d7efb..e05bf2afc 100644 --- a/Modules/Compiler/PathScale-Fortran.cmake +++ b/Modules/Compiler/PathScale-Fortran.cmake @@ -2,3 +2,5 @@ include(Compiler/PathScale) __compiler_pathscale(Fortran) SET(CMAKE_Fortran_MODDIR_FLAG "-module ") +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixedform") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-freeform") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index a41b45456..86d6def34 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -1,4 +1,6 @@ SET(CMAKE_Fortran_VERBOSE_FLAG "-v") +set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC") SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-G") diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake index d88b3f32f..e7026f11a 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_FORMAT_FIXED_FLAG "-qfixed") # [=] +set(CMAKE_Fortran_FORMAT_FREE_FLAG "-qfree") # [=f90|ibm] + SET(CMAKE_Fortran_MODDIR_FLAG "-qmoddir=") SET(CMAKE_Fortran_DEFINE_FLAG "-WF,-D") diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 26125d9d3..f2b01f138 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1048,6 +1048,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) false, "Variables that Control the Build"); + cm->DefineProperty + ("CMAKE_Fortran_FORMAT", cmProperty::VARIABLE, + "Set to FIXED or FREE to indicate the Fortran source layout.", + "This variable is used to initialize the Fortran_FORMAT " + "property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + cm->DefineProperty ("CMAKE_Fortran_MODULE_DIRECTORY", cmProperty::VARIABLE, "Fortran module output directory.", diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 7da35eb26..1d1e8da01 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2916,6 +2916,31 @@ std::string cmLocalGenerator::EscapeForCMake(const char* str) return result; } +//---------------------------------------------------------------------------- +cmLocalGenerator::FortranFormat +cmLocalGenerator::GetFortranFormat(const char* value) +{ + FortranFormat format = FortranFormatNone; + if(value && *value) + { + std::vector fmt; + cmSystemTools::ExpandListArgument(value, fmt); + for(std::vector::iterator fi = fmt.begin(); + fi != fmt.end(); ++fi) + { + if(*fi == "FIXED") + { + format = FortranFormatFixed; + } + if(*fi == "FREE") + { + format = FortranFormatFree; + } + } + } + return format; +} + //---------------------------------------------------------------------------- std::string cmLocalGenerator::GetTargetDirectory(cmTarget const&) const diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index a204a73d5..cfc09dc32 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -244,6 +244,14 @@ public: /** Escape the given string as an argument in a CMake script. */ std::string EscapeForCMake(const char* str); + enum FortranFormat + { + FortranFormatNone, + FortranFormatFixed, + FortranFormatFree + }; + FortranFormat GetFortranFormat(const char* value); + /** Return the directories into which object files will be put. * There maybe more than one for fat binary systems like OSX. */ diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index b6a7c33df..54175845e 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -689,6 +689,16 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, } } + if(this->FortranProject) + { + switch(this->GetFortranFormat(target.GetProperty("Fortran_FORMAT"))) + { + case FortranFormatFixed: flags += " -fixed"; break; + case FortranFormatFree: flags += " -free"; break; + default: break; + } + } + // Add the target-specific flags. if(const char* targetFlags = target.GetProperty("COMPILE_FLAGS")) { @@ -1363,6 +1373,21 @@ cmLocalVisualStudio7GeneratorFCInfo fc.CompileFlags = cflags; needfc = true; } + if(lg->FortranProject) + { + switch(lg->GetFortranFormat(sf.GetProperty("Fortran_FORMAT"))) + { + case cmLocalGenerator::FortranFormatFixed: + fc.CompileFlags = "-fixed " + fc.CompileFlags; + needfc = true; + break; + case cmLocalGenerator::FortranFormatFree: + fc.CompileFlags = "-free " + fc.CompileFlags; + needfc = true; + break; + default: break; + } + } if(const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) { fc.CompileDefs = cdefs; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index d0df8f076..8b9119400 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -501,6 +501,35 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) ); } +//---------------------------------------------------------------------------- +void +cmMakefileTargetGenerator +::AppendFortranFormatFlags(std::string& flags, cmSourceFile& source) +{ + const char* srcfmt = source.GetProperty("Fortran_FORMAT"); + cmLocalGenerator::FortranFormat format = + this->LocalGenerator->GetFortranFormat(srcfmt); + if(format == cmLocalGenerator::FortranFormatNone) + { + const char* tgtfmt = this->Target->GetProperty("Fortran_FORMAT"); + format = this->LocalGenerator->GetFortranFormat(tgtfmt); + } + const char* var = 0; + switch (format) + { + case cmLocalGenerator::FortranFormatFixed: + var = "CMAKE_Fortran_FORMAT_FIXED_FLAG"; break; + case cmLocalGenerator::FortranFormatFree: + var = "CMAKE_Fortran_FORMAT_FREE_FLAG"; break; + default: break; + } + if(var) + { + this->LocalGenerator->AppendFlags( + flags, this->Makefile->GetDefinition(var)); + } +} + //---------------------------------------------------------------------------- void cmMakefileTargetGenerator @@ -562,6 +591,12 @@ cmMakefileTargetGenerator } } + // Add Fortran format flags. + if(strcmp(lang, "Fortran") == 0) + { + this->AppendFortranFormatFlags(flags, source); + } + // Add flags from source file properties. if (source.GetProperty("COMPILE_FLAGS")) { diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index b68f8bf3b..674cd1306 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -112,6 +112,8 @@ protected: // Return the a string with -F flags on apple std::string GetFrameworkFlags(); + void AppendFortranFormatFlags(std::string& flags, cmSourceFile& source); + // append intertarget dependencies void AppendTargetDepends(std::vector& depends); diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index dfa2c0b3f..cd94753cb 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -436,6 +436,15 @@ void cmSourceFile::DefineProperties(cmake *cm) "is really an object file and should not be compiled. " "It will still be linked into the target though."); + cm->DefineProperty + ("Fortran_FORMAT", cmProperty::SOURCE_FILE, + "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 Fortran_FORMAT property if all " + "source files in a target share the same format."); + cm->DefineProperty ("GENERATED", cmProperty::SOURCE_FILE, "Is this source file generated as part of the build process.", diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 4969b65af..a7f50f680 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -918,6 +918,17 @@ void cmTarget::DefineProperties(cmake *cm) "module is loaded. " ); + cm->DefineProperty + ("Fortran_FORMAT", cmProperty::TARGET, + "Set to FIXED or FREE to indicate the Fortran source layout.", + "This property tells CMake whether the Fortran source files " + "in a target use fixed-format or free-format. " + "CMake will pass the corresponding format flag to the compiler. " + "Use the source-specific Fortran_FORMAT property to change the " + "format of a specific source file. " + "If the variable CMAKE_Fortran_FORMAT is set when a target " + "is created its value is used to initialize this property."); + cm->DefineProperty ("Fortran_MODULE_DIRECTORY", cmProperty::TARGET, "Specify output directory for Fortran modules provided by the target.", @@ -1138,6 +1149,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); + this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0); this->SetPropertyDefault("AUTOMOC", 0); diff --git a/Tests/Fortran/CMakeLists.txt b/Tests/Fortran/CMakeLists.txt index c216529f4..ba0bdcc78 100644 --- a/Tests/Fortran/CMakeLists.txt +++ b/Tests/Fortran/CMakeLists.txt @@ -161,8 +161,10 @@ if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) add_executable(test_use_in_comment_fixedform test_use_in_comment_fixedform.f) + set_property(SOURCE test_use_in_comment_fixedform.f PROPERTY Fortran_FORMAT FIXED) add_executable(test_use_in_comment_freeform test_use_in_comment_freeform.f90) + set_property(SOURCE test_use_in_comment_freeform.f90 PROPERTY Fortran_FORMAT FREE) add_executable(test_in_interface in_interface/main.f90 diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index 3c4f0e7e4..d57a8b295 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -4,6 +4,9 @@ message("CTEST_FULL_OUTPUT ") # create a library with hello and world functions add_library(FortranOnlylib hello.f world.f) +set_property(TARGET FortranOnlylib PROPERTY Fortran_FORMAT FIXED) +set_property(SOURCE world.f PROPERTY Fortran_FORMAT FREE) + # create an executable that calls hello and world add_executable(FortranOnly testf.f) target_link_libraries(FortranOnly FortranOnlylib) diff --git a/Tests/FortranOnly/world.f b/Tests/FortranOnly/world.f index deae3fa72..342b24431 100644 --- a/Tests/FortranOnly/world.f +++ b/Tests/FortranOnly/world.f @@ -1,5 +1,4 @@ - SUBROUTINE WORLD - - PRINT *, 'World!' - - END +! Free-format ".f" file to test Fortran_FORMAT property +SUBROUTINE WORLD + PRINT *, 'World!' +END