From 0842b08463d14d6c7e27dcb4cda278805cce6e5f Mon Sep 17 00:00:00 2001 From: Tim Gallagher Date: Wed, 5 Nov 2014 13:37:25 -0500 Subject: Makefile: Refactor checks for lang-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 | 42 ++++++++++++++++++-------------- Source/cmMakefileTargetGenerator.cxx | 14 ++++++++--- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index c18e027..0e40c04 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -315,36 +315,42 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() // Check whether preprocessing and assembly rules make sense. // They make sense only for C and C++ sources. - bool lang_is_c_or_cxx = false; + bool lang_has_preprocessor = false; + bool lang_has_assembly = false; + for(std::vector::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 and 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..a1f4141 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 and 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) { -- cgit v0.12 From b6b37e303786e48c305cb83011ce5fa6cf71e359 Mon Sep 17 00:00:00 2001 From: Tim Gallagher Date: Wed, 5 Nov 2014 13:43:06 -0500 Subject: Makefile: Add assembly and preprocessed targets for Fortran Extend the FortranOnly test to cover "make .i" targets. --- 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 | 2 +- Modules/Platform/HP-UX-HP-Fortran.cmake | 3 +++ Modules/Platform/IRIX.cmake | 8 ++++++++ Source/cmLocalUnixMakefileGenerator3.cxx | 5 +++-- Source/cmMakefileTargetGenerator.cxx | 5 +++-- Tests/FortranOnly/CMakeLists.txt | 26 ++++++++++++++++++++++++++ Tests/FortranOnly/preprocess.F | 5 +++++ Tests/FortranOnly/test_preprocess.cmake | 7 +++++++ 13 files changed, 65 insertions(+), 15 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 " -S -o ") +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE " -E > ") 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 " -E > ") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE " -S -o ") 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 " -E > ") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE " -S -o ") diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake index f1c9158..ae9df4e 100644 --- a/Modules/Compiler/XL-Fortran.cmake +++ b/Modules/Compiler/XL-Fortran.cmake @@ -12,6 +12,6 @@ set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D") # -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. +# xlf: 1501-214 (W) command option E reserved for future use - ignored 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 " -E > ") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE " -S -o ") 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 " -E > ") + set (CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE + " -S " + "mv `basename \"\" | sed 's/\\.[^./]*$$//'`.s " + ) +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 0e40c04..ff8ba8b 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -322,9 +322,10 @@ 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 and 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; lang_has_assembly = true; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index a1f4141..1e01f11 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -702,11 +702,12 @@ cmMakefileTargetGenerator vars.Defines = definesString.c_str(); - // At the moment, it is assumed that C and 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..1b2651d 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -66,3 +66,29 @@ 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 + # Remove bogus file some compilers leave behind. + COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/preprocess.s + 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..f7df457 --- /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() -- cgit v0.12