Here's to hoping 3rd time's the charm...

Also, what version of gfortran do you have that requires both -E and -cpp to do 
the preprocessing? I don't need that on my version, I'm using 4.7.1. There may 
need to be more sophisticated logic in the Compiler module to add -cpp to the 
command line for versions that require it.

Tim

----- Original Message -----
From: "Brad King" <[email protected]>
To: "Tim Gallagher" <[email protected]>
Cc: [email protected]
Sent: Wednesday, November 5, 2014 12:55:04 PM
Subject: Re: [cmake-developers] Assembly/preprocessed targets for Fortran

On 11/05/2014 12:14 PM, Tim Gallagher wrote:
> I have attached an updated patch

Thanks!  Please split this into two patches.  The first one should
do the refactoring of the variable name and corresponding logic
with no functionality changes.  The second one can add the Fortran
feature.

Also please keep C++ source lines to 79 columns or below.

The FortranOnly test fails for me with:

 f95: error: gfortran does not support -E without -cpp

because it doesn't enable preprocessing for lower-case extensions.
You'll need to add another .F test source with an upper-case
extension to activate preprocessing without special flags.

Thanks,
-Brad

From 4d7eafbcf923fda5f541bc9e5fbdb1004e29ecf1 Mon Sep 17 00:00:00 2001
From: Tim Gallagher <[email protected]>
Date: Wed, 5 Nov 2014 13:37:25 -0500
Subject: [PATCH] Refactored the checks for language-specific targets and
 export compile cmds

The checks are now split into languages that are able to generate
assembly listings, languages that are able to generate
preprocessed listings and languages that are able to export the
compile commands.
---
 Source/cmLocalUnixMakefileGenerator3.cxx |   44 +++++++++++++++++-------------
 Source/cmMakefileTargetGenerator.cxx     |   14 +++++++---
 2 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c18e027..e6b125b 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -314,37 +314,43 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
                                      lo->first.c_str(), lo->second);

     // Check whether preprocessing and assembly rules make sense.
-    // They make sense only for C and C++ sources.
-    bool lang_is_c_or_cxx = false;
+    // They make sense only for C/C++ sources.
+    bool lang_has_preprocessor = false;
+    bool lang_has_assembly = false;
+
     for(std::vector<LocalObjectEntry>::const_iterator ei =
           lo->second.begin(); ei != lo->second.end(); ++ei)
       {
-      if(ei->Language == "C" || ei->Language == "CXX")
+      if(ei->Language == "C" ||
+         ei->Language == "CXX")
         {
-        lang_is_c_or_cxx = true;
+       // Right now, C/C++ have both a preprocessor and the
+       // ability to generate assembly code
+        lang_has_preprocessor = true;
+        lang_has_assembly = true;
         break;
         }
       }

     // Add convenience rules for preprocessed and assembly files.
-    if(lang_is_c_or_cxx && (do_preprocess_rules || do_assembly_rules))
+    if(lang_has_preprocessor && do_preprocess_rules)
       {
       std::string::size_type dot_pos = lo->first.rfind(".");
       std::string base = lo->first.substr(0, dot_pos);
-      if(do_preprocess_rules)
-        {
-        this->WriteObjectConvenienceRule(
-          ruleFileStream, "target to preprocess a source file",
-          (base + ".i").c_str(), lo->second);
-          lo->second.HasPreprocessRule = true;
-        }
-      if(do_assembly_rules)
-        {
-        this->WriteObjectConvenienceRule(
-          ruleFileStream, "target to generate assembly for a file",
-          (base + ".s").c_str(), lo->second);
-          lo->second.HasAssembleRule = true;
-        }
+      this->WriteObjectConvenienceRule(
+        ruleFileStream, "target to preprocess a source file",
+       (base + ".i").c_str(), lo->second);
+      lo->second.HasPreprocessRule = true;
+      }
+
+    if(lang_has_assembly && do_assembly_rules)
+      {
+      std::string::size_type dot_pos = lo->first.rfind(".");
+      std::string base = lo->first.substr(0, dot_pos);
+      this->WriteObjectConvenienceRule(
+       ruleFileStream, "target to generate assembly for a file",
+       (base + ".s").c_str(), lo->second);
+      lo->second.HasAssembleRule = true;
       }
     }

diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 1adcb8a..6b98b35 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -702,7 +702,13 @@ cmMakefileTargetGenerator

   vars.Defines = definesString.c_str();

-  bool lang_is_c_or_cxx = ((lang == "C") || (lang == "CXX"));
+  // At the moment, it is assumed that C/C++ have both
+  // assembly and preprocessor capabilities. The same is true for the
+  // ability to export compile commands
+  bool lang_has_preprocessor = ((lang == "C") ||
+                                (lang == "CXX"));
+  bool const lang_has_assembly = lang_has_preprocessor;
+  bool const lang_can_export_cmds = lang_has_preprocessor;

   // Construct the compile rules.
   {
@@ -715,7 +721,7 @@ cmMakefileTargetGenerator
   cmSystemTools::ExpandListArgument(compileRule, compileCommands);

   if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
-      lang_is_c_or_cxx && compileCommands.size() == 1)
+      lang_can_export_cmds && compileCommands.size() == 1)
     {
     std::string compileCommand = compileCommands[0];
     this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
@@ -771,9 +777,9 @@ cmMakefileTargetGenerator
       }
     }

-  bool do_preprocess_rules = lang_is_c_or_cxx &&
+  bool do_preprocess_rules = lang_has_preprocessor &&
     this->LocalGenerator->GetCreatePreprocessedSourceRules();
-  bool do_assembly_rules = lang_is_c_or_cxx &&
+  bool do_assembly_rules = lang_has_assembly &&
     this->LocalGenerator->GetCreateAssemblySourceRules();
   if(do_preprocess_rules || do_assembly_rules)
     {
--
1.7.10.4
From e94fec9be688c2e5d468eb5147bad12a84facdeb Mon Sep 17 00:00:00 2001
From: Tim Gallagher <[email protected]>
Date: Wed, 5 Nov 2014 13:43:06 -0500
Subject: [PATCH] Added assembly and preprocessed targets for Fortran

---
 Modules/Compiler/GNU-Fortran.cmake       |    5 -----
 Modules/Compiler/HP-Fortran.cmake        |    3 +++
 Modules/Compiler/Intel-Fortran.cmake     |    3 +++
 Modules/Compiler/PGI-Fortran.cmake       |    5 -----
 Modules/Compiler/SunPro-Fortran.cmake    |    3 +++
 Modules/Compiler/XL-Fortran.cmake        |    4 ----
 Modules/Platform/HP-UX-HP-Fortran.cmake  |    3 +++
 Modules/Platform/IRIX.cmake              |    8 ++++++++
 Modules/Platform/IRIX64.cmake            |    9 +++++++++
 Source/cmLocalUnixMakefileGenerator3.cxx |    7 ++++---
 Source/cmMakefileTargetGenerator.cxx     |    5 +++--
 Tests/FortranOnly/CMakeLists.txt         |   24 ++++++++++++++++++++++++
 Tests/FortranOnly/preprocess.F           |    5 +++++
 Tests/FortranOnly/test_preprocess.cmake  |    7 +++++++
 14 files changed, 72 insertions(+), 19 deletions(-)
 create mode 100644 Tests/FortranOnly/preprocess.F
 create mode 100644 Tests/FortranOnly/test_preprocess.cmake

diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake
index 313ccbd..dfd7927 100644
--- a/Modules/Compiler/GNU-Fortran.cmake
+++ b/Modules/Compiler/GNU-Fortran.cmake
@@ -8,10 +8,5 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
 set(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os")
 set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3")

-# We require updates to CMake C++ code to support preprocessing rules
-# for Fortran.
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
-
 # Fortran-specific feature flags.
 set(CMAKE_Fortran_MODDIR_FLAG -J)
diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake
index cc56b46..ad821ab 100644
--- a/Modules/Compiler/HP-Fortran.cmake
+++ b/Modules/Compiler/HP-Fortran.cmake
@@ -1,3 +1,6 @@
 set(CMAKE_Fortran_VERBOSE_FLAG "-v")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "+source=fixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free")
+
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake
index 84f6182..9ebac5a 100644
--- a/Modules/Compiler/Intel-Fortran.cmake
+++ b/Modules/Compiler/Intel-Fortran.cmake
@@ -7,3 +7,6 @@ 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")
+
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake
index 264c23e..2866254 100644
--- a/Modules/Compiler/PGI-Fortran.cmake
+++ b/Modules/Compiler/PGI-Fortran.cmake
@@ -7,9 +7,4 @@ 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")

-# We require updates to CMake C++ code to support preprocessing rules
-# for Fortran.
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
-
 set(CMAKE_Fortran_MODDIR_FLAG "-module ")
diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake
index 18e75b9..c38d5a5 100644
--- a/Modules/Compiler/SunPro-Fortran.cmake
+++ b/Modules/Compiler/SunPro-Fortran.cmake
@@ -16,3 +16,6 @@ set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG")
 set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-g -xO2 -DNDEBUG")
 set(CMAKE_Fortran_MODDIR_FLAG "-moddir=")
 set(CMAKE_Fortran_MODPATH_FLAG "-M")
+
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake
index f1c9158..dfe2166 100644
--- a/Modules/Compiler/XL-Fortran.cmake
+++ b/Modules/Compiler/XL-Fortran.cmake
@@ -11,7 +11,3 @@ set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D")
 # -qthreaded     = Ensures that all optimizations will be thread-safe
 # -qhalt=e       = Halt on error messages (rather than just severe errors)
 set(CMAKE_Fortran_FLAGS_INIT "-qthreaded -qhalt=e")
-
-# We require updates to CMake C++ code to support preprocessing rules for Fortran.
-set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
-set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
diff --git a/Modules/Platform/HP-UX-HP-Fortran.cmake b/Modules/Platform/HP-UX-HP-Fortran.cmake
index 30acab8..e5c5d10 100644
--- a/Modules/Platform/HP-UX-HP-Fortran.cmake
+++ b/Modules/Platform/HP-UX-HP-Fortran.cmake
@@ -1,2 +1,5 @@
 include(Platform/HP-UX-HP)
 __hpux_compiler_hp(Fortran)
+
+set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Platform/IRIX.cmake b/Modules/Platform/IRIX.cmake
index 03e98cc..12b0f37 100644
--- a/Modules/Platform/IRIX.cmake
+++ b/Modules/Platform/IRIX.cmake
@@ -31,6 +31,14 @@ if(NOT CMAKE_COMPILER_IS_GNUCXX)
     )
 endif()

+if(NOT CMAKE_COMPILER_IS_GNUG77)
+  set (CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+  set (CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE
+    "<CMAKE_Fortran_COMPILER> <FLAGS> -S <SOURCE>"
+    "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+    )
+endif()
+
 # Initialize C link type selection flags.  These flags are used when
 # building a shared library, shared module, or executable that links
 # to other libraries to select whether to use the static or shared
diff --git a/Modules/Platform/IRIX64.cmake b/Modules/Platform/IRIX64.cmake
index 5acbd81..6ec6dfc 100644
--- a/Modules/Platform/IRIX64.cmake
+++ b/Modules/Platform/IRIX64.cmake
@@ -59,6 +59,15 @@ if(NOT CMAKE_COMPILER_IS_GNUCXX)
     )
 endif()

+
+if(NOT CMAKE_COMPILER_IS_GNUG77)
+  set (CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+  set (CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE
+    "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE>"
+    "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
+    )
+endif()
+
 # Initialize C link type selection flags.  These flags are used when
 # building a shared library, shared module, or executable that links
 # to other libraries to select whether to use the static or shared
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index e6b125b..0504b3c 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -322,11 +322,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
          lo->second.begin(); ei != lo->second.end(); ++ei)
       {
       if(ei->Language == "C" ||
-         ei->Language == "CXX")
+         ei->Language == "CXX" ||
+         ei->Language == "Fortran")
         {
-       // Right now, C/C++ have both a preprocessor and the
+       // Right now, C, C++ and Fortran have both a preprocessor and the
        // ability to generate assembly code
         lang_has_preprocessor = true;
         break;
         }
       }
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 6b98b35..a4a7d0e 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -702,0 +702,0 @@ cmMakefileTargetGenerator

   vars.Defines = definesString.c_str();

-  // At the moment, it is assumed that C/C++ have both
+  // At the moment, it is assumed that C, C++ and Fortran have both
   // assembly and preprocessor capabilities. The same is true for the
   // ability to export compile commands
   bool lang_has_preprocessor = ((lang == "C") ||
-                                (lang == "CXX"));
+                                (lang == "CXX" ||
+                                (lang == "Fortran"));
   bool const lang_has_assembly = lang_has_preprocessor;
   bool const lang_can_export_cmds = lang_has_preprocessor;

diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt
index f55e727..46a12b4 100644
--- a/Tests/FortranOnly/CMakeLists.txt
+++ b/Tests/FortranOnly/CMakeLists.txt
@@ -66,3 +66,27 @@ if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL)
       "${err}")
   endif()
 endif()
+
+# Test generation of preprocessed sources.
+if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
+  if(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
+    # Skip running this part of the test on certain platforms
+    # until they are fixed.
+    set(MAYBE_ALL ALL)
+    list(LENGTH CMAKE_OSX_ARCHITECTURES ARCH_COUNT)
+    if(ARCH_COUNT GREATER 1)
+      # OSX does not support preprocessing more than one architecture.
+      set(MAYBE_ALL)
+    endif()
+
+    add_executable(preprocess preprocess.F)
+
+    # Custom target to try preprocessing invocation.
+    add_custom_target(test_preprocess ${MAYBE_ALL}
+      COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/preprocess.dir/preprocess.F.i
+      COMMAND ${CMAKE_MAKE_PROGRAM} preprocess.i
+      COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
+      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+      )
+  endif()
+endif()
diff --git a/Tests/FortranOnly/preprocess.F b/Tests/FortranOnly/preprocess.F
new file mode 100644
index 0000000..d9131f6
--- /dev/null
+++ b/Tests/FortranOnly/preprocess.F
@@ -0,0 +1,5 @@
+       PROGRAM PREPRO
+#ifndef TEST_PREPROCESSOR
+       PRINT *, 'Hello'
+#endif
+       END
diff --git a/Tests/FortranOnly/test_preprocess.cmake b/Tests/FortranOnly/test_preprocess.cmake
new file mode 100644
index 0000000..29ebdac
--- /dev/null
+++ b/Tests/FortranOnly/test_preprocess.cmake
@@ -0,0 +1,7 @@
+set(TEST_FILE CMakeFiles/preprocess.dir/preprocess.F.i)
+file(READ ${TEST_FILE} CONTENTS)
+if("${CONTENTS}" MATCHES "PRINT *")
+  message(STATUS "${TEST_FILE} created successfully!")
+else()
+  message(FATAL_ERROR "${TEST_FILE} creation failed!")
+endif()
--
1.7.10.4
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to