Sorry about the TABs, I guess emacs defaults to it and I never noticed. I have attached an updated patch where the tabs are removed and the test for CMAKE_EXPORT_COMPILE_COMMANDS is also removed.
Tim ----- Original Message ----- From: "Brad King" <[email protected]> To: "tim gallagher" <[email protected]>, [email protected] Sent: Wednesday, November 5, 2014 11:26:26 AM Subject: Re: [cmake-developers] Assembly/preprocessed targets for Fortran On 11/04/2014 06:37 PM, Tim Gallagher wrote: > I have attached the patch to enable the targets for Fortran. Thanks. Please update it to avoid using hard TABs for indentation. Also in the CompileCommandOutput test hunk: > -project (CompileCommandOutput CXX) > +project (CompileCommandOutput) > +enable_language(CXX) > +enable_language(Fortran) there are a couple problems: - By removing any explicit languages from the project() call it will enable C and CXX by default. Use NONE to suppress that. - We cannot assume that Fortran will be available. The other Fortran tests are all guarded by availability of a Fortran compiler. The test for CMAKE_EXPORT_COMPILE_COMMANDS was already missing for C, so let's just skip Fortran for the test too. They can be fixed together as a separate change later. Thanks, -Brad
From ff4a9ffe8a03822e87bc7d26a144ab2ca1e1ced6 Mon Sep 17 00:00:00 2001 From: Tim Gallagher <[email protected]> Date: Wed, 5 Nov 2014 12:07:33 -0500 Subject: [PATCH] Enabled the generation of assembly and preprocessor targets for Fortran. The Makefile generator has been updated to create .i and .s targets for Fortran files. The variable lang_is_c_or_cxx has been changed and split into variables to indicate languages which can be preprocessed, generate assembly, or have their compile commands output. This should allow for more fine-grained control over these behaviors if languages can handle some or all of those features. The modules have been updated to set the CMAKE_Fortran_CREATE_* flags required. This has been tested successfully on Intel and GNU suites but remains untested for the others. The assumption is that other Fortran compilers handle the options the same way their respective C/C++ compilers handle it. Testing has been added to the FortranOnly test to verify the preprocessor works. This test behaves the same as the test in the Complex test for C++. There is no test for assembly in C/C++ however, so there is not one in Fortran either. --- 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 | 43 +++++++++++++++++------------- Source/cmMakefileTargetGenerator.cxx | 13 ++++++--- Tests/FortranOnly/CMakeLists.txt | 22 +++++++++++++++ Tests/FortranOnly/test_preprocess.cmake | 7 +++++ 13 files changed, 91 insertions(+), 37 deletions(-) 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 c18e027..e1ea30d 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -314,37 +314,42 @@ 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++ and Fortran 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" || ei->Language == "Fortran") { - lang_is_c_or_cxx = true; + // Right now, C, C++ and Fortran 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..d1fecd8 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -702,7 +702,12 @@ 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++ 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 == "Fortran")); + bool const lang_has_assembly = lang_has_preprocessor; + bool const lang_can_export_cmds = lang_has_preprocessor; // Construct the compile rules. { @@ -715,7 +720,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 +776,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) { diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index f55e727..8ed05f1 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -66,3 +66,25 @@ 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() + + # Custom target to try preprocessing invocation. + add_custom_target(test_preprocess ${MAYBE_ALL} + COMMAND ${CMAKE_COMMAND} -E remove CMakeFile/world.dir/world.i + COMMAND ${CMAKE_MAKE_PROGRAM} world.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/test_preprocess.cmake b/Tests/FortranOnly/test_preprocess.cmake new file mode 100644 index 0000000..f90471c --- /dev/null +++ b/Tests/FortranOnly/test_preprocess.cmake @@ -0,0 +1,7 @@ +set(TEST_FILE CMakeFiles/FortranOnlylib.dir/world.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
