mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-07 06:09:52 -06:00
Ninja: Fix Fortran support with response files
The Ninja generator splits preprocessing and compilation steps for Fortran. Fix this logic to work when using response files for compilation so that it works for the preprocessing step too. This fixes behavior under `CMAKE_NINJA_FORCE_RESPONSE_FILE`. Issue: #17877
This commit is contained in:
@@ -445,24 +445,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
cmMakefile* mf = this->GetMakefile();
|
||||
|
||||
std::string flags = "$FLAGS";
|
||||
std::string rspfile;
|
||||
std::string rspcontent;
|
||||
|
||||
std::string responseFlag;
|
||||
bool const lang_supports_response = !(lang == "RC" || lang == "CUDA");
|
||||
if (lang_supports_response && this->ForceResponseFile()) {
|
||||
std::string const responseFlagVar =
|
||||
"CMAKE_" + lang + "_RESPONSE_FILE_FLAG";
|
||||
std::string responseFlag =
|
||||
this->Makefile->GetSafeDefinition(responseFlagVar);
|
||||
responseFlag = this->Makefile->GetSafeDefinition(responseFlagVar);
|
||||
if (responseFlag.empty()) {
|
||||
responseFlag = "@";
|
||||
}
|
||||
rspfile = "$RSP_FILE";
|
||||
responseFlag += rspfile;
|
||||
rspcontent = " $DEFINES $INCLUDES $FLAGS";
|
||||
flags = std::move(responseFlag);
|
||||
vars.Defines = "";
|
||||
vars.Includes = "";
|
||||
}
|
||||
|
||||
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
|
||||
@@ -514,6 +506,18 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
// 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.
|
||||
std::string ppRspFile;
|
||||
std::string ppRspContent;
|
||||
if (!responseFlag.empty()) {
|
||||
ppRspFile = "$RSP_FILE";
|
||||
ppRspContent = std::string(" ") + ppVars.Defines + " " +
|
||||
ppVars.Includes + " " + ppFlags;
|
||||
ppFlags = responseFlag + ppRspFile;
|
||||
ppVars.Defines = "";
|
||||
ppVars.Includes = "";
|
||||
}
|
||||
|
||||
ppVars.Flags = ppFlags.c_str();
|
||||
|
||||
// Rule for preprocessing source file.
|
||||
@@ -544,13 +548,11 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
ppComment << "Rule for preprocessing " << lang << " files.";
|
||||
std::ostringstream ppDesc;
|
||||
ppDesc << "Building " << lang << " preprocessed $out";
|
||||
this->GetGlobalGenerator()->AddRule(this->LanguagePreprocessRule(lang),
|
||||
ppCmdLine, ppDesc.str(),
|
||||
ppComment.str(), ppDepfile, ppDeptype,
|
||||
/*rspfile*/ "",
|
||||
/*rspcontent*/ "",
|
||||
/*restat*/ "",
|
||||
/*generator*/ false);
|
||||
this->GetGlobalGenerator()->AddRule(
|
||||
this->LanguagePreprocessRule(lang), ppCmdLine, ppDesc.str(),
|
||||
ppComment.str(), ppDepfile, ppDeptype, ppRspFile, ppRspContent,
|
||||
/*restat*/ "",
|
||||
/*generator*/ false);
|
||||
}
|
||||
|
||||
if (needDyndep) {
|
||||
@@ -587,6 +589,18 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
|
||||
/*generator*/ false);
|
||||
}
|
||||
|
||||
// If using a response file, move defines, includes, and flags into it.
|
||||
std::string rspfile;
|
||||
std::string rspcontent;
|
||||
if (!responseFlag.empty()) {
|
||||
rspfile = "$RSP_FILE";
|
||||
rspcontent =
|
||||
std::string(" ") + vars.Defines + " " + vars.Includes + " " + flags;
|
||||
flags = responseFlag + rspfile;
|
||||
vars.Defines = "";
|
||||
vars.Includes = "";
|
||||
}
|
||||
|
||||
// Tell ninja dependency format so all deps can be loaded into a database
|
||||
std::string deptype;
|
||||
std::string depfile;
|
||||
@@ -1019,9 +1033,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
|
||||
ppVars);
|
||||
|
||||
std::string const ppRspFile = ppFileName + ".rsp";
|
||||
|
||||
this->GetGlobalGenerator()->WriteBuild(
|
||||
this->GetBuildFileStream(), ppComment, ppRule, ppOutputs, ppImplicitOuts,
|
||||
ppExplicitDeps, ppImplicitDeps, ppOrderOnlyDeps, ppVars);
|
||||
ppExplicitDeps, ppImplicitDeps, ppOrderOnlyDeps, ppVars, ppRspFile,
|
||||
commandLineLengthLimit);
|
||||
}
|
||||
if (needDyndep) {
|
||||
std::string const dyndep = this->GetDyndepFilePath(language);
|
||||
|
||||
@@ -121,6 +121,9 @@ if(CMAKE_GENERATOR STREQUAL "Ninja")
|
||||
-DCMAKE_C_OUTPUT_EXTENSION=${CMAKE_C_OUTPUT_EXTENSION}
|
||||
-DCMAKE_SHARED_LIBRARY_PREFIX=${CMAKE_SHARED_LIBRARY_PREFIX}
|
||||
-DCMAKE_SHARED_LIBRARY_SUFFIX=${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
if(CMAKE_Fortran_COMPILER)
|
||||
list(APPEND Ninja_ARGS -DTEST_Fortran=1)
|
||||
endif()
|
||||
add_RunCMake_test(Ninja)
|
||||
endif()
|
||||
add_RunCMake_test(CTest)
|
||||
|
||||
2
Tests/RunCMake/Ninja/RspFileC.cmake
Normal file
2
Tests/RunCMake/Ninja/RspFileC.cmake
Normal file
@@ -0,0 +1,2 @@
|
||||
set(ENV{CMAKE_NINJA_FORCE_RESPONSE_FILE} 1)
|
||||
enable_language(C)
|
||||
2
Tests/RunCMake/Ninja/RspFileCXX.cmake
Normal file
2
Tests/RunCMake/Ninja/RspFileCXX.cmake
Normal file
@@ -0,0 +1,2 @@
|
||||
set(ENV{CMAKE_NINJA_FORCE_RESPONSE_FILE} 1)
|
||||
enable_language(CXX)
|
||||
2
Tests/RunCMake/Ninja/RspFileFortran.cmake
Normal file
2
Tests/RunCMake/Ninja/RspFileFortran.cmake
Normal file
@@ -0,0 +1,2 @@
|
||||
set(ENV{CMAKE_NINJA_FORCE_RESPONSE_FILE} 1)
|
||||
enable_language(Fortran)
|
||||
@@ -40,6 +40,12 @@ run_CMP0058(NEW-by)
|
||||
|
||||
run_cmake(CustomCommandDepfile)
|
||||
|
||||
run_cmake(RspFileC)
|
||||
run_cmake(RspFileCXX)
|
||||
if(TEST_Fortran)
|
||||
run_cmake(RspFileFortran)
|
||||
endif()
|
||||
|
||||
function(run_CommandConcat)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CommandConcat-build)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
|
||||
Reference in New Issue
Block a user