mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 14:19:59 -05:00
Merge topic 'fortran-preprocess-property'
3888de23daNinja: Skip Fortran preprocessing if Fortran_PREPROCESS is OFF66c4e87282Ninja: Add helper functions to generate Fortran build5cca1ec893Ninja: Add helper functions to generate Fortran preprocess ruleb0a6161190Fortran: Add Fortran_PREPROCESS property Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !4659
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -466,6 +467,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
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.
|
||||
|
||||
When using the :generator:`Ninja` generator, all source files are
|
||||
first preprocessed in order to generate module dependency
|
||||
information. Setting this property to ``OFF`` will make ``Ninja``
|
||||
skip this step.
|
||||
|
||||
Consider using the target-wide :prop_tgt:`Fortran_PREPROCESS` property
|
||||
if all source files in a target need to be preprocessed.
|
||||
@@ -0,0 +1,23 @@
|
||||
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.
|
||||
|
||||
When using the :generator:`Ninja` generator, all source files are
|
||||
first preprocessed in order to generate module dependency
|
||||
information. Setting this property to ``OFF`` will make ``Ninja``
|
||||
skip this 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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -283,6 +283,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 },
|
||||
@@ -681,6 +682,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.
|
||||
@@ -1473,6 +1486,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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
+237
-137
@@ -106,7 +106,16 @@ std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
|
||||
std::string const& lang, const std::string& config) const
|
||||
{
|
||||
return cmStrCat(
|
||||
lang, "_PREPROCESS__",
|
||||
lang, "_PREPROCESS_SCAN__",
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
|
||||
'_', config);
|
||||
}
|
||||
|
||||
std::string cmNinjaTargetGenerator::LanguageDependencyRule(
|
||||
std::string const& lang, const std::string& config) const
|
||||
{
|
||||
return cmStrCat(
|
||||
lang, "_SCAN__",
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
|
||||
'_', config);
|
||||
}
|
||||
@@ -183,6 +192,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.
|
||||
@@ -508,6 +518,91 @@ void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language,
|
||||
this->WriteCompileRule(language, config);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Create the command to run the dependency scanner
|
||||
std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
|
||||
const std::string& lang, const std::string& ppFile,
|
||||
bool needDyndep, const std::string& ddiFile)
|
||||
{
|
||||
std::string ccmd =
|
||||
cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, " --lang=", lang,
|
||||
" --pp=", ppFile, " --dep=$DEP_FILE");
|
||||
if (needDyndep) {
|
||||
ccmd = cmStrCat(ccmd, " --obj=$OBJ_FILE --ddi=", ddiFile);
|
||||
}
|
||||
return ccmd;
|
||||
}
|
||||
|
||||
// Helper function to create dependency scanning rule, with optional
|
||||
// explicit preprocessing step if preprocessCommand is non-empty
|
||||
cmNinjaRule GetPreprocessScanRule(
|
||||
const std::string& ruleName, cmRulePlaceholderExpander::RuleVariables& vars,
|
||||
const std::string& responseFlag, const std::string& flags,
|
||||
const std::string& launcher,
|
||||
cmRulePlaceholderExpander* const rulePlaceholderExpander,
|
||||
std::string scanCommand, cmLocalNinjaGenerator* generator,
|
||||
const std::string& preprocessCommand = "")
|
||||
{
|
||||
cmNinjaRule rule(ruleName);
|
||||
// Explicit preprocessing always uses a depfile.
|
||||
rule.DepType = ""; // no deps= for multiple outputs
|
||||
rule.DepFile = "$DEP_FILE";
|
||||
|
||||
cmRulePlaceholderExpander::RuleVariables ppVars;
|
||||
ppVars.CMTargetName = vars.CMTargetName;
|
||||
ppVars.CMTargetType = vars.CMTargetType;
|
||||
ppVars.Language = vars.Language;
|
||||
ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
|
||||
ppVars.PreprocessedSource = "$out";
|
||||
ppVars.DependencyFile = rule.DepFile.c_str();
|
||||
|
||||
// Preprocessing uses the original source, compilation uses
|
||||
// preprocessed output or original source
|
||||
ppVars.Source = vars.Source;
|
||||
vars.Source = "$in";
|
||||
|
||||
// Copy preprocessor definitions to the preprocessor rule.
|
||||
ppVars.Defines = vars.Defines;
|
||||
|
||||
// Copy include directories to the preprocessor rule. The Fortran
|
||||
// compilation rule still needs them for the INCLUDE directive.
|
||||
ppVars.Includes = vars.Includes;
|
||||
|
||||
// Preprocessing and compilation use the same flags.
|
||||
std::string ppFlags = flags;
|
||||
|
||||
// If using a response file, move defines, includes, and flags into it.
|
||||
if (!responseFlag.empty()) {
|
||||
rule.RspFile = "$RSP_FILE";
|
||||
rule.RspContent =
|
||||
cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
|
||||
ppFlags = cmStrCat(responseFlag, rule.RspFile);
|
||||
ppVars.Defines = "";
|
||||
ppVars.Includes = "";
|
||||
}
|
||||
|
||||
ppVars.Flags = ppFlags.c_str();
|
||||
|
||||
// Rule for preprocessing source file.
|
||||
std::vector<std::string> ppCmds;
|
||||
|
||||
if (!preprocessCommand.empty()) {
|
||||
// Lookup the explicit preprocessing rule.
|
||||
cmExpandList(preprocessCommand, ppCmds);
|
||||
for (std::string& i : ppCmds) {
|
||||
i = cmStrCat(launcher, i);
|
||||
rulePlaceholderExpander->ExpandRuleVariables(generator, i, ppVars);
|
||||
}
|
||||
}
|
||||
|
||||
// Run CMake dependency scanner on either preprocessed output or source file
|
||||
ppCmds.emplace_back(std::move(scanCommand));
|
||||
rule.Command = generator->BuildCommandLine(ppCmds);
|
||||
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
const std::string& config)
|
||||
{
|
||||
@@ -565,82 +660,42 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
|
||||
|
||||
if (explicitPP) {
|
||||
cmNinjaRule rule(this->LanguagePreprocessRule(lang, config));
|
||||
// Explicit preprocessing always uses a depfile.
|
||||
rule.DepType = ""; // no deps= for multiple outputs
|
||||
rule.DepFile = "$DEP_FILE";
|
||||
// Combined preprocessing and dependency scanning
|
||||
const auto ppScanCommand = GetScanCommand(
|
||||
cmakeCmd, tdi, lang, "$out", needDyndep, "$DYNDEP_INTERMEDIATE_FILE");
|
||||
const auto ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
|
||||
|
||||
cmRulePlaceholderExpander::RuleVariables ppVars;
|
||||
ppVars.CMTargetName = vars.CMTargetName;
|
||||
ppVars.CMTargetType = vars.CMTargetType;
|
||||
ppVars.Language = vars.Language;
|
||||
ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
|
||||
ppVars.PreprocessedSource = "$out";
|
||||
ppVars.DependencyFile = rule.DepFile.c_str();
|
||||
|
||||
// Preprocessing uses the original source,
|
||||
// compilation uses preprocessed output.
|
||||
ppVars.Source = vars.Source;
|
||||
vars.Source = "$in";
|
||||
|
||||
// Preprocessing and compilation use the same flags.
|
||||
std::string ppFlags = flags;
|
||||
|
||||
if (!compilePPWithDefines) {
|
||||
// Move preprocessor definitions to the preprocessor rule.
|
||||
ppVars.Defines = vars.Defines;
|
||||
vars.Defines = "";
|
||||
} else {
|
||||
// Copy preprocessor definitions to the preprocessor rule.
|
||||
ppVars.Defines = vars.Defines;
|
||||
}
|
||||
|
||||
// Copy include directories to the preprocessor rule. The Fortran
|
||||
// compilation rule still needs them for the INCLUDE directive.
|
||||
ppVars.Includes = vars.Includes;
|
||||
|
||||
// If using a response file, move defines, includes, and flags into it.
|
||||
if (!responseFlag.empty()) {
|
||||
rule.RspFile = "$RSP_FILE";
|
||||
rule.RspContent =
|
||||
cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
|
||||
ppFlags = cmStrCat(responseFlag, rule.RspFile);
|
||||
ppVars.Defines = "";
|
||||
ppVars.Includes = "";
|
||||
}
|
||||
|
||||
ppVars.Flags = ppFlags.c_str();
|
||||
|
||||
// Rule for preprocessing source file.
|
||||
std::vector<std::string> ppCmds;
|
||||
{
|
||||
// Lookup the explicit preprocessing rule.
|
||||
std::string ppVar = cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE");
|
||||
cmExpandList(this->GetMakefile()->GetRequiredDefinition(ppVar), ppCmds);
|
||||
}
|
||||
|
||||
for (std::string& i : ppCmds) {
|
||||
i = cmStrCat(launcher, i);
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
|
||||
i, ppVars);
|
||||
}
|
||||
|
||||
// Run CMake dependency scanner on preprocessed output.
|
||||
{
|
||||
std::string ccmd =
|
||||
cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi,
|
||||
" --lang=", lang, " --pp=$out --dep=$DEP_FILE");
|
||||
if (needDyndep) {
|
||||
ccmd += " --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE";
|
||||
}
|
||||
ppCmds.emplace_back(std::move(ccmd));
|
||||
}
|
||||
rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds);
|
||||
auto ppRule = GetPreprocessScanRule(
|
||||
this->LanguagePreprocessRule(lang, config), vars, responseFlag, flags,
|
||||
launcher, rulePlaceholderExpander.get(), ppScanCommand,
|
||||
this->GetLocalGenerator(), mf->GetRequiredDefinition(ppVar));
|
||||
|
||||
// Write the rule for preprocessing file of the given language.
|
||||
rule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
|
||||
rule.Description = cmStrCat("Building ", lang, " preprocessed $out");
|
||||
this->GetGlobalGenerator()->AddRule(rule);
|
||||
ppRule.Comment = cmStrCat("Rule for preprocessing ", lang, " files.");
|
||||
ppRule.Description = cmStrCat("Building ", lang, " preprocessed $out");
|
||||
|
||||
this->GetGlobalGenerator()->AddRule(ppRule);
|
||||
|
||||
if (!compilePPWithDefines) {
|
||||
// Remove preprocessor definitions from compilation step
|
||||
vars.Defines = "";
|
||||
}
|
||||
|
||||
// Just dependency scanning for files that have preprocessing turned off
|
||||
const auto scanCommand =
|
||||
GetScanCommand(cmakeCmd, tdi, lang, "$in", needDyndep, "$out");
|
||||
|
||||
auto scanRule = GetPreprocessScanRule(
|
||||
this->LanguageDependencyRule(lang, config), vars, "", flags, launcher,
|
||||
rulePlaceholderExpander.get(), scanCommand, this->GetLocalGenerator());
|
||||
|
||||
// Write the rule for generating dependencies for the given language.
|
||||
scanRule.Comment = cmStrCat("Rule for generating ", lang,
|
||||
" dependencies on non-preprocessed files.");
|
||||
scanRule.Description =
|
||||
cmStrCat("Generating ", lang, " dependencies for $in");
|
||||
|
||||
this->GetGlobalGenerator()->AddRule(scanRule);
|
||||
}
|
||||
|
||||
if (needDyndep) {
|
||||
@@ -996,6 +1051,82 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
cmNinjaBuild GetPreprocessOrScanBuild(
|
||||
const std::string& ruleName, const std::string& ppFileName, bool compilePP,
|
||||
bool compilePPWithDefines, cmNinjaBuild& objBuild, cmNinjaVars& vars,
|
||||
const std::string& depFileName, bool needDyndep,
|
||||
const std::string& objectFileName)
|
||||
{
|
||||
// Explicit preprocessing and dependency
|
||||
cmNinjaBuild ppBuild(ruleName);
|
||||
|
||||
if (!ppFileName.empty()) {
|
||||
ppBuild.Outputs.push_back(ppFileName);
|
||||
ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
|
||||
} else {
|
||||
ppBuild.RspFile = "$out.rsp";
|
||||
}
|
||||
|
||||
if (compilePP) {
|
||||
// Move compilation dependencies to the preprocessing build statement.
|
||||
std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
|
||||
std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
|
||||
std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
|
||||
std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
|
||||
|
||||
// The actual compilation will now use the preprocessed source.
|
||||
objBuild.ExplicitDeps.push_back(ppFileName);
|
||||
} else {
|
||||
// Copy compilation dependencies to the preprocessing build statement.
|
||||
ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
|
||||
ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
|
||||
ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
|
||||
ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
|
||||
}
|
||||
|
||||
// Preprocessing and compilation generally use the same flags.
|
||||
ppBuild.Variables["FLAGS"] = vars["FLAGS"];
|
||||
|
||||
if (compilePP && !compilePPWithDefines) {
|
||||
// Move preprocessor definitions to the preprocessor build statement.
|
||||
std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
|
||||
} else {
|
||||
// Copy preprocessor definitions to the preprocessor build statement.
|
||||
ppBuild.Variables["DEFINES"] = vars["DEFINES"];
|
||||
}
|
||||
|
||||
// Copy include directories to the preprocessor build statement. The
|
||||
// Fortran compilation build statement still needs them for the INCLUDE
|
||||
// directive.
|
||||
ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
|
||||
|
||||
// Explicit preprocessing always uses a depfile.
|
||||
ppBuild.Variables["DEP_FILE"] = depFileName;
|
||||
if (compilePP) {
|
||||
// The actual compilation does not need a depfile because it
|
||||
// depends on the already-preprocessed source.
|
||||
vars.erase("DEP_FILE");
|
||||
}
|
||||
|
||||
if (needDyndep) {
|
||||
// Tell dependency scanner the object file that will result from
|
||||
// compiling the source.
|
||||
ppBuild.Variables["OBJ_FILE"] = objectFileName;
|
||||
|
||||
// Tell dependency scanner where to store dyndep intermediate results.
|
||||
std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
|
||||
if (ppFileName.empty()) {
|
||||
ppBuild.Outputs.push_back(ddiFile);
|
||||
} else {
|
||||
ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
|
||||
ppBuild.ImplicitOuts.push_back(ddiFile);
|
||||
}
|
||||
}
|
||||
return ppBuild;
|
||||
}
|
||||
}
|
||||
|
||||
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
cmSourceFile const* source, const std::string& config,
|
||||
const std::string& fileConfig, bool firstForConfig)
|
||||
@@ -1134,36 +1265,39 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
// For some cases we do an explicit preprocessor invocation.
|
||||
bool const explicitPP = this->NeedExplicitPreprocessing(language);
|
||||
if (explicitPP) {
|
||||
cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language, config));
|
||||
|
||||
std::string const ppFileName =
|
||||
this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
|
||||
ppBuild.Outputs.push_back(ppFileName);
|
||||
|
||||
ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
|
||||
|
||||
bool const compilePP = this->UsePreprocessedSource(language);
|
||||
bool const compilePPWithDefines =
|
||||
compilePP && this->CompilePreprocessedSourceWithDefines(language);
|
||||
if (compilePP) {
|
||||
// Move compilation dependencies to the preprocessing build statement.
|
||||
std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps);
|
||||
std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps);
|
||||
std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps);
|
||||
std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]);
|
||||
|
||||
// The actual compilation will now use the preprocessed source.
|
||||
objBuild.ExplicitDeps.push_back(ppFileName);
|
||||
} else {
|
||||
// Copy compilation dependencies to the preprocessing build statement.
|
||||
ppBuild.ExplicitDeps = objBuild.ExplicitDeps;
|
||||
ppBuild.ImplicitDeps = objBuild.ImplicitDeps;
|
||||
ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps;
|
||||
ppBuild.Variables["IN_ABS"] = vars["IN_ABS"];
|
||||
// If source/target has preprocessing turned off, we still need to
|
||||
// generate an explicit dependency step
|
||||
const auto srcpp = source->GetSafeProperty("Fortran_PREPROCESS");
|
||||
cmOutputConverter::FortranPreprocess preprocess =
|
||||
cmOutputConverter::GetFortranPreprocess(srcpp);
|
||||
if (preprocess == cmOutputConverter::FortranPreprocess::Unset) {
|
||||
const auto& tgtpp =
|
||||
this->GeneratorTarget->GetSafeProperty("Fortran_PREPROCESS");
|
||||
preprocess = cmOutputConverter::GetFortranPreprocess(tgtpp);
|
||||
}
|
||||
|
||||
// Preprocessing and compilation generally use the same flags.
|
||||
ppBuild.Variables["FLAGS"] = vars["FLAGS"];
|
||||
bool const compilePP = this->UsePreprocessedSource(language) &&
|
||||
(preprocess != cmOutputConverter::FortranPreprocess::NotNeeded);
|
||||
bool const compilePPWithDefines =
|
||||
compilePP && this->CompilePreprocessedSourceWithDefines(language);
|
||||
|
||||
std::string const ppFileName = compilePP
|
||||
? this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config))
|
||||
: "";
|
||||
|
||||
std::string const buildName = compilePP
|
||||
? this->LanguagePreprocessRule(language, config)
|
||||
: this->LanguageDependencyRule(language, config);
|
||||
|
||||
const auto depExtension = compilePP ? ".pp.d" : ".d";
|
||||
const std::string depFileName =
|
||||
this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
cmStrCat(objectFileName, depExtension), cmOutputConverter::SHELL);
|
||||
|
||||
cmNinjaBuild ppBuild = GetPreprocessOrScanBuild(
|
||||
buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars,
|
||||
depFileName, needDyndep, objectFileName);
|
||||
|
||||
if (compilePP) {
|
||||
// In case compilation requires flags that are incompatible with
|
||||
@@ -1171,22 +1305,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
std::string const& postFlag = this->Makefile->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_", language, "_POSTPROCESS_FLAG"));
|
||||
this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
|
||||
}
|
||||
|
||||
if (compilePP && !compilePPWithDefines) {
|
||||
// Move preprocessor definitions to the preprocessor build statement.
|
||||
std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]);
|
||||
} else {
|
||||
// Copy preprocessor definitions to the preprocessor build statement.
|
||||
ppBuild.Variables["DEFINES"] = vars["DEFINES"];
|
||||
}
|
||||
|
||||
// Copy include directories to the preprocessor build statement. The
|
||||
// Fortran compilation build statement still needs them for the INCLUDE
|
||||
// directive.
|
||||
ppBuild.Variables["INCLUDES"] = vars["INCLUDES"];
|
||||
|
||||
if (compilePP) {
|
||||
// Prepend source file's original directory as an include directory
|
||||
// so e.g. Fortran INCLUDE statements can look for files in it.
|
||||
std::vector<std::string> sourceDirectory;
|
||||
@@ -1200,28 +1319,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]);
|
||||
}
|
||||
|
||||
// Explicit preprocessing always uses a depfile.
|
||||
ppBuild.Variables["DEP_FILE"] =
|
||||
this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
cmStrCat(objectFileName, ".pp.d"), cmOutputConverter::SHELL);
|
||||
if (compilePP) {
|
||||
// The actual compilation does not need a depfile because it
|
||||
// depends on the already-preprocessed source.
|
||||
vars.erase("DEP_FILE");
|
||||
}
|
||||
|
||||
if (needDyndep) {
|
||||
// Tell dependency scanner the object file that will result from
|
||||
// compiling the source.
|
||||
ppBuild.Variables["OBJ_FILE"] = objectFileName;
|
||||
|
||||
// Tell dependency scanner where to store dyndep intermediate results.
|
||||
if (firstForConfig && needDyndep) {
|
||||
std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
|
||||
ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
|
||||
ppBuild.ImplicitOuts.push_back(ddiFile);
|
||||
if (firstForConfig) {
|
||||
this->Configs[config].DDIFiles[language].push_back(ddiFile);
|
||||
}
|
||||
this->Configs[config].DDIFiles[language].push_back(ddiFile);
|
||||
}
|
||||
|
||||
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
|
||||
|
||||
@@ -70,6 +70,8 @@ protected:
|
||||
const std::string& config) const;
|
||||
std::string LanguagePreprocessRule(std::string const& lang,
|
||||
const std::string& config) const;
|
||||
std::string LanguageDependencyRule(std::string const& lang,
|
||||
const std::string& config) const;
|
||||
bool NeedExplicitPreprocessing(std::string const& lang) const;
|
||||
std::string LanguageDyndepRule(std::string const& lang,
|
||||
const std::string& config) const;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -116,3 +116,46 @@ 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()
|
||||
|
||||
# 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()
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
SUBROUTINE NOPREPROCESS_SOURCE_FPP
|
||||
INTEGER F
|
||||
END
|
||||
@@ -0,0 +1,3 @@
|
||||
SUBROUTINE NOPREPROCESS_SOURCE_LOWER
|
||||
INTEGER F
|
||||
END
|
||||
@@ -0,0 +1,3 @@
|
||||
SUBROUTINE NOPREPROCESS_SOURCE_UPPER
|
||||
INTEGER F
|
||||
END
|
||||
@@ -0,0 +1,3 @@
|
||||
SUBROUTINE NOPREPROCESS_TARGET_FPP
|
||||
INTEGER F
|
||||
END
|
||||
@@ -0,0 +1,3 @@
|
||||
SUBROUTINE NOPREPROCESS_TARGET_LOWER
|
||||
INTEGER F
|
||||
END
|
||||
@@ -0,0 +1,3 @@
|
||||
SUBROUTINE NOPREPROCESS_TARGET_UPPER
|
||||
INTEGER F
|
||||
END
|
||||
@@ -0,0 +1,4 @@
|
||||
#define int INTEGER
|
||||
PROGRAM PREPRO
|
||||
int f
|
||||
END
|
||||
@@ -0,0 +1,4 @@
|
||||
#define int INTEGER
|
||||
PROGRAM PREPRO
|
||||
int f
|
||||
END
|
||||
Reference in New Issue
Block a user