Explorar el Código

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.
Brad King hace 14 años
padre
commit
5c0c635a09

+ 2 - 0
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")

+ 2 - 0
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")

+ 2 - 0
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")

+ 3 - 0
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")

+ 2 - 0
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")

+ 2 - 0
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")

+ 2 - 0
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")

+ 2 - 0
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")

+ 3 - 0
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")
 

+ 2 - 0
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")

+ 2 - 0
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")

+ 3 - 0
Modules/Compiler/XL-Fortran.cmake

@@ -1,6 +1,9 @@
 include(Compiler/XL)
 __compiler_xl(Fortran)
 
+set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-qfixed") # [=<right_margin>]
+set(CMAKE_Fortran_FORMAT_FREE_FLAG "-qfree") # [=f90|ibm]
+
 SET(CMAKE_Fortran_MODDIR_FLAG "-qmoddir=")
 
 SET(CMAKE_Fortran_DEFINE_FLAG "-WF,-D")

+ 9 - 0
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.",

+ 25 - 0
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<std::string> fmt;
+    cmSystemTools::ExpandListArgument(value, fmt);
+    for(std::vector<std::string>::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

+ 8 - 0
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.
    */

+ 25 - 0
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;

+ 35 - 0
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"))
     {

+ 2 - 0
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<std::string>& depends);
 

+ 9 - 0
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.",

+ 12 - 0
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);

+ 2 - 0
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

+ 3 - 0
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)

+ 4 - 5
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