Fortran: Add Fortran_PREPROCESS property

Issue: #18870
This commit is contained in:
Peter Hill 2020-04-24 11:52:41 +01:00 committed by Brad King
parent d3d53eefee
commit b0a6161190
37 changed files with 243 additions and 4 deletions

View File

@ -170,6 +170,7 @@ syn keyword cmakeProperty contained
\ FRAMEWORK_VERSION
\ Fortran_FORMAT
\ Fortran_MODULE_DIRECTORY
\ Fortran_PREPROCESS
\ GENERATED
\ GENERATOR_FILE_NAME
\ GENERATOR_IS_MULTI_CONFIG
@ -1019,6 +1020,7 @@ syn keyword cmakeVariable contained
\ CMAKE_Fortran_MODULE_DIRECTORY
\ CMAKE_Fortran_OUTPUT_EXTENSION
\ CMAKE_Fortran_PLATFORM_ID
\ CMAKE_Fortran_PREPROCESS
\ CMAKE_Fortran_SIMULATE_ID
\ CMAKE_Fortran_SIMULATE_VERSION
\ CMAKE_Fortran_SIZEOF_DATA_PTR

View File

@ -201,6 +201,7 @@ Properties on Targets
/prop_tgt/FOLDER
/prop_tgt/Fortran_FORMAT
/prop_tgt/Fortran_MODULE_DIRECTORY
/prop_tgt/Fortran_PREPROCESS
/prop_tgt/FRAMEWORK
/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
/prop_tgt/FRAMEWORK_VERSION
@ -465,6 +466,7 @@ Properties on Source Files
/prop_sf/COMPILE_OPTIONS
/prop_sf/EXTERNAL_OBJECT
/prop_sf/Fortran_FORMAT
/prop_sf/Fortran_PREPROCESS
/prop_sf/GENERATED
/prop_sf/HEADER_FILE_ONLY
/prop_sf/INCLUDE_DIRECTORIES

View File

@ -391,6 +391,7 @@ Variables that Control the Build
/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
/variable/CMAKE_Fortran_FORMAT
/variable/CMAKE_Fortran_MODULE_DIRECTORY
/variable/CMAKE_Fortran_PREPROCESS
/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE
/variable/CMAKE_GLOBAL_AUTOGEN_TARGET
/variable/CMAKE_GLOBAL_AUTOGEN_TARGET_NAME

View File

@ -4,7 +4,9 @@ Fortran_FORMAT
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
:prop_tgt:`Fortran_FORMAT` property if all source files in a target
share the same format.
fixed-format or free-format. CMake will pass the corresponding format flag
to the compiler. Consider using the target-wide :prop_tgt:`Fortran_FORMAT`
property if all source files in a target share the same format.
.. note:: For some compilers, ``NAG``, ``PGI`` and ``Solaris Studio``,
setting this to ``OFF`` will have no effect.

View File

@ -0,0 +1,12 @@
Fortran_PREPROCESS
------------------
Control whether the Fortran source file should be unconditionally preprocessed.
If unset or empty, rely on the compiler to determine whether the file
should be preprocessed. If explicitly set to ``OFF`` then the file
does not need to be preprocessed. If explicitly set to ``ON``, then
the file does need to be preprocessed as part of the compilation step.
Consider using the target-wide :prop_tgt:`Fortran_PREPROCESS` property
if all source files in a target need to be preprocessed.

View File

@ -0,0 +1,18 @@
Fortran_PREPROCESS
------------------
Control whether the Fortran source file should be unconditionally
preprocessed.
If unset or empty, rely on the compiler to determine whether the file
should be preprocessed. If explicitly set to ``OFF`` then the file does not
need to be preprocessed. If explicitly set to ``ON``, then the file does
need to be preprocessed as part of the compilation step.
Use the source-specific :prop_sf:`Fortran_PREPROCESS` property if a single
file needs to be preprocessed. If the variable
:variable:`CMAKE_Fortran_PREPROCESS` is set when a target is created its
value is used to initialize this property.
.. note:: For some compilers, ``NAG``, ``PGI`` and ``Solaris Studio``,
setting this to ``OFF`` will have no effect.

View File

@ -0,0 +1,6 @@
fortran-preprocess-property
---------------------------
* The :prop_tgt:`Fortran_PREPROCESS` target property and
:prop_sf:`Fortran_PREPROCESS` source-file property were added to
control preprocessing of Fortran source files.

View File

@ -0,0 +1,8 @@
CMAKE_Fortran_PREPROCESS
------------------------
Default value for :prop_tgt:`Fortran_PREPROCESS` of targets.
This variable is used to initialize the :prop_tgt:`Fortran_PREPROCESS`
property on all the targets. See that target property for additional
information.

View File

@ -9,3 +9,5 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v")
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree")
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-X")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-no-cpp")

View File

@ -11,3 +11,11 @@ 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")
if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 8.5)
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-eT")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-dT")
else()
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-eZ")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-dZ")
endif()

View File

@ -11,3 +11,6 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
set(CMAKE_Fortran_MODDIR_FLAG "-J")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")

View File

@ -9,3 +9,5 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-no-cpp")

View File

@ -10,6 +10,11 @@ set(CMAKE_Fortran_PREPROCESS_SOURCE
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.4)
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")
endif()
set(CMAKE_Fortran_POSTPROCESS_FLAG "-fpreprocessed")
# No -DNDEBUG for Fortran.

View File

@ -7,3 +7,6 @@ set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES>
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG ",")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "+cpp=yes")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "+cpp=no")

View File

@ -15,3 +15,5 @@ set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <IN
set(CMAKE_Fortran_PREPROCESS_SOURCE
"<CMAKE_Fortran_COMPILER> -fpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nofpp")

View File

@ -37,3 +37,4 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free")
set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-PIC")
set(CMAKE_Fortran_COMPILE_OPTIONS_PIE "-PIC")
set(CMAKE_Fortran_RESPONSE_FILE_LINK_FLAG "-Wl,@")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp")

View File

@ -6,6 +6,7 @@ set(CMAKE_Fortran_SUBMODULE_EXT ".mod")
set(CMAKE_Fortran_PREPROCESS_SOURCE
"<CMAKE_Fortran_COMPILER> -Mpreprocess <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-Mpreprocess")
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-Mnofreeform")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform")

View File

@ -4,3 +4,6 @@ __compiler_pathscale(Fortran)
set(CMAKE_Fortran_MODDIR_FLAG "-module ")
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixedform")
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-freeform")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")

View File

@ -30,3 +30,5 @@ set(CMAKE_Fortran_PREPROCESS_SOURCE
set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -F -fpp <SOURCE> -o <PREPROCESSED_SOURCE>")
set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-fpp")

View File

@ -23,3 +23,8 @@ set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
set(CMAKE_Fortran_PREPROCESS_SOURCE
"<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -qpreprocess -qnoobject -qsuppress=1517-020 -tF -B \"${CMAKE_CURRENT_LIST_DIR}/XL-Fortran/\" -WF,--cpp,\"${CMAKE_Fortran_XL_CPP}\",--out,<PREPROCESSED_SOURCE> <SOURCE>"
)
if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 15.1.6)
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-qpreprocess")
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-qnopreprocess")
endif()

View File

@ -98,6 +98,34 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
}
}
void cmCommonTargetGenerator::AppendFortranPreprocessFlags(
std::string& flags, cmSourceFile const& source)
{
const std::string srcpp = source.GetSafeProperty("Fortran_PREPROCESS");
cmOutputConverter::FortranPreprocess preprocess =
cmOutputConverter::GetFortranPreprocess(srcpp);
if (preprocess == cmOutputConverter::FortranPreprocess::Unset) {
std::string const& tgtpp =
this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS");
preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
}
const char* var = nullptr;
switch (preprocess) {
case cmOutputConverter::FortranPreprocess::Needed:
var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON";
break;
case cmOutputConverter::FortranPreprocess::NotNeeded:
var = "CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF";
break;
default:
break;
}
if (var) {
this->LocalCommonGenerator->AppendCompileOptions(
flags, this->Makefile->GetSafeDefinition(var));
}
}
std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
const std::string& config,
const std::string& arch)

View File

@ -45,6 +45,9 @@ protected:
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
void AppendFortranPreprocessFlags(std::string& flags,
cmSourceFile const& source);
virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
const std::string& config) = 0;

View File

@ -284,6 +284,7 @@ void cmLocalVisualStudio7Generator::WriteConfigurations(
}
cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = {
{ "Preprocess", "fpp", "Run Preprocessor on files", "preprocessYes", 0 },
{ "Preprocess", "nofpp", "Run Preprocessor on files", "preprocessNo", 0 },
{ "SuppressStartupBanner", "nologo", "SuppressStartupBanner", "true", 0 },
{ "SourceFileFormat", "fixed", "Use Fixed Format", "fileFormatFixed", 0 },
{ "SourceFileFormat", "free", "Use Free Format", "fileFormatFree", 0 },
@ -682,6 +683,18 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
default:
break;
}
switch (cmOutputConverter::GetFortranPreprocess(
target->GetSafeProperty("Fortran_PREPROCESS"))) {
case cmOutputConverter::FortranPreprocess::Needed:
flags += " -fpp";
break;
case cmOutputConverter::FortranPreprocess::NotNeeded:
flags += " -nofpp";
break;
default:
break;
}
}
// Get preprocessor definitions for this directory.
@ -1474,6 +1487,20 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
if (lg->FortranProject) {
switch (cmOutputConverter::GetFortranPreprocess(
sf.GetSafeProperty("Fortran_PREPROCESS"))) {
case cmOutputConverter::FortranPreprocess::Needed:
fc.CompileFlags = cmStrCat("-fpp ", fc.CompileFlags);
needfc = true;
break;
case cmOutputConverter::FortranPreprocess::NotNeeded:
fc.CompileFlags = cmStrCat("-nofpp ", fc.CompileFlags);
needfc = true;
break;
default:
break;
}
switch (cmOutputConverter::GetFortranFormat(
sf.GetSafeProperty("Fortran_FORMAT"))) {
case cmOutputConverter::FortranFormatFixed:

View File

@ -541,6 +541,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Add Fortran format flags.
if (lang == "Fortran") {
this->AppendFortranFormatFlags(flags, source);
this->AppendFortranPreprocessFlags(flags, source);
}
// Add flags from source file properties.

View File

@ -183,6 +183,7 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
// Add Fortran format flags.
if (language == "Fortran") {
this->AppendFortranFormatFlags(flags, *source);
this->AppendFortranPreprocessFlags(flags, *source);
}
// Add source file specific flags.

View File

@ -170,6 +170,17 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
return format;
}
cmOutputConverter::FortranPreprocess cmOutputConverter::GetFortranPreprocess(
cm::string_view value)
{
if (value.empty()) {
return FortranPreprocess::Unset;
}
return cmIsOn(value) ? FortranPreprocess::Needed
: FortranPreprocess::NotNeeded;
}
void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
{
this->LinkScriptShell = linkScriptShell;

View File

@ -95,6 +95,14 @@ public:
};
static FortranFormat GetFortranFormat(cm::string_view value);
enum class FortranPreprocess
{
Unset,
NotNeeded,
Needed
};
static FortranPreprocess GetFortranPreprocess(cm::string_view value);
private:
cmState* GetState() const;

View File

@ -307,6 +307,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("Fortran_FORMAT");
initProp("Fortran_MODULE_DIRECTORY");
initProp("Fortran_COMPILER_LAUNCHER");
initProp("Fortran_PREPROCESS");
initProp("GNUtoMS");
initProp("OSX_ARCHITECTURES");
initProp("IOS_INSTALL_COMBINED");

View File

@ -116,3 +116,48 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
set_property(TARGET IntelIfDef PROPERTY Fortran_FORMAT FIXED)
target_compile_definitions(IntelIfDef PRIVATE SOME_DEF)
endif()
# Skip these tests if compiler/version doesn't have preprocessing flags
if((CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 4.4)
OR (CMAKE_Fortran_COMPILER_ID STREQUAL "XL" AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 15.1.6))
set(test_pp_flags 0)
else()
set(test_pp_flags 1)
endif()
if(test_pp_flags)
# Test that we can always preprocess a target
add_executable(preprocess_target preprocess2.f)
set_property(TARGET preprocess_target PROPERTY Fortran_PREPROCESS ON)
# Test that we can preprocess a single source file
add_executable(preprocess_source preprocess3.f)
set_property(SOURCE preprocess3.f PROPERTY Fortran_PREPROCESS ON)
endif()
if(NOT CMAKE_GENERATOR MATCHES "Ninja")
# Test that neither the compiler nor CMake performs unnecessary preprocessing.
add_library(no_preprocess_target_lower STATIC no_preprocess_target_lower.f)
target_compile_options(no_preprocess_target_lower PRIVATE -DINTEGER=nonsense)
set_property(TARGET no_preprocess_target_lower PROPERTY Fortran_PREPROCESS OFF)
add_library(no_preprocess_source_lower STATIC no_preprocess_source_lower.f)
target_compile_options(no_preprocess_source_lower PRIVATE -DINTEGER=nonsense)
set_property(SOURCE no_preprocess_source_lower.f PROPERTY Fortran_PREPROCESS OFF)
# Test that we can explicitly not preprocess a target or source.
# This will not work on certain compilers due to either missing a
# "don't preprocess" flag, or due to choice of file extension.
if(test_pp_flags AND NOT CMAKE_Fortran_COMPILER_ID MATCHES "(Flang|NAG|PGI|SunPro|XL)")
add_library(no_preprocess_target STATIC no_preprocess_target_upper.F)
target_compile_options(no_preprocess_target PRIVATE -DINTEGER=nonsense)
add_library(no_preprocess_source STATIC no_preprocess_source_upper.F)
target_compile_options(no_preprocess_source PRIVATE -DINTEGER=nonsense)
if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "Cray"
AND NOT "${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "Intel;MSVC")
target_sources(no_preprocess_target PRIVATE no_preprocess_target_fpp.fpp)
target_sources(no_preprocess_source PRIVATE no_preprocess_source_fpp.fpp)
endif()
set_property(TARGET no_preprocess_target PROPERTY Fortran_PREPROCESS OFF)
set_property(SOURCE no_preprocess_source_upper.F no_preprocess_source_fpp.fpp PROPERTY Fortran_PREPROCESS OFF)
endif()
endif()

View File

@ -0,0 +1,3 @@
SUBROUTINE NOPREPROCESS_SOURCE_FPP
INTEGER F
END

View File

@ -0,0 +1,3 @@
SUBROUTINE NOPREPROCESS_SOURCE_LOWER
INTEGER F
END

View File

@ -0,0 +1,3 @@
SUBROUTINE NOPREPROCESS_SOURCE_UPPER
INTEGER F
END

View File

@ -0,0 +1,3 @@
SUBROUTINE NOPREPROCESS_TARGET_FPP
INTEGER F
END

View File

@ -0,0 +1,3 @@
SUBROUTINE NOPREPROCESS_TARGET_LOWER
INTEGER F
END

View File

@ -0,0 +1,3 @@
SUBROUTINE NOPREPROCESS_TARGET_UPPER
INTEGER F
END

View File

@ -0,0 +1,4 @@
#define int INTEGER
PROGRAM PREPRO
int f
END

View File

@ -0,0 +1,4 @@
#define int INTEGER
PROGRAM PREPRO
int f
END