From b5c2163293c08e8e53203d86a069713e06874886 Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Sat, 16 Jan 2021 17:37:23 +0100 Subject: Ninja: add_custom_command(DEPFILE): Ensure dependencies consistency Fixes: #21694 --- Source/cmCustomCommandGenerator.cxx | 14 +++----- Source/cmDependsCompiler.cxx | 13 ++----- Source/cmGccDepfileReader.cxx | 4 +-- Source/cmTransformDepfile.cxx | 41 ++++++++++++++++------ Source/cmTransformDepfile.h | 4 ++- Source/cmcmd.cxx | 36 +++++++++++++++---- Tests/RunCMake/BuildDepends/CMakeLists.txt | 2 +- .../BuildDepends/CustomCommandDepfile.cmake | 2 +- .../BuildDepends/DepfileSubdir/CMakeLists.txt | 2 +- Tests/RunCMake/CMakeLists.txt | 5 ++- Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake | 4 +-- Tests/RunCMake/TransformDepfile/deps-unix.d.txt | 8 ++--- Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt | 8 ++--- Tests/RunCMake/TransformDepfile/deps-windows.d.txt | 8 ++--- .../TransformDepfile/deps-windows.tlog.txt | 8 ++--- .../TransformDepfile/invalid-gcc-result.txt | 2 +- .../TransformDepfile/invalid-tlog-result.txt | 2 +- 17 files changed, 99 insertions(+), 64 deletions(-) diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index c67497a..4329caf 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -200,6 +200,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( argv.push_back(cmSystemTools::GetCMakeCommand()); argv.emplace_back("-E"); argv.emplace_back("cmake_transform_depfile"); + argv.push_back(this->LG->GetGlobalGenerator()->GetName()); switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) { case cmDepfileFormat::GccDepfile: argv.emplace_back("gccdepfile"); @@ -208,15 +209,10 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( argv.emplace_back("vstlog"); break; } - if (this->LG->GetCurrentBinaryDirectory() == - this->LG->GetBinaryDirectory()) { - argv.emplace_back("./"); - } else { - argv.push_back(cmStrCat(this->LG->MaybeConvertToRelativePath( - this->LG->GetBinaryDirectory(), - this->LG->GetCurrentBinaryDirectory()), - '/')); - } + argv.push_back(this->LG->GetSourceDirectory()); + argv.push_back(this->LG->GetCurrentSourceDirectory()); + argv.push_back(this->LG->GetBinaryDirectory()); + argv.push_back(this->LG->GetCurrentBinaryDirectory()); argv.push_back(this->GetFullDepfile()); argv.push_back(this->GetInternalDepfile()); diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx index ec31f68..2b48df9 100644 --- a/Source/cmDependsCompiler.cxx +++ b/Source/cmDependsCompiler.cxx @@ -97,17 +97,8 @@ bool cmDependsCompiler::CheckDependencies( std::vector depends; if (format == "custom"_s) { - std::string prefix; - if (this->LocalGenerator->GetCurrentBinaryDirectory() != - this->LocalGenerator->GetBinaryDirectory()) { - prefix = - cmStrCat(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), - this->LocalGenerator->GetCurrentBinaryDirectory()), - '/'); - } - - auto deps = cmReadGccDepfile(depFile.c_str(), prefix); + auto deps = cmReadGccDepfile( + depFile.c_str(), this->LocalGenerator->GetCurrentBinaryDirectory()); if (!deps) { continue; } diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx index 8253375..6436baa 100644 --- a/Source/cmGccDepfileReader.cxx +++ b/Source/cmGccDepfileReader.cxx @@ -24,7 +24,7 @@ cm::optional cmReadGccDepfile(const char* filePath, for (auto& dep : *deps) { for (auto& rule : dep.rules) { if (!prefix.empty() && !cmSystemTools::FileIsFullPath(rule)) { - rule = cmStrCat(prefix, rule); + rule = cmStrCat(prefix, '/', rule); } if (cmSystemTools::FileIsFullPath(rule)) { rule = cmSystemTools::CollapseFullPath(rule); @@ -33,7 +33,7 @@ cm::optional cmReadGccDepfile(const char* filePath, } for (auto& path : dep.paths) { if (!prefix.empty() && !cmSystemTools::FileIsFullPath(path)) { - path = cmStrCat(prefix, path); + path = cmStrCat(prefix, '/', path); } if (cmSystemTools::FileIsFullPath(path)) { path = cmSystemTools::CollapseFullPath(path); diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx index b91e1ce..78aa4b2 100644 --- a/Source/cmTransformDepfile.cxx +++ b/Source/cmTransformDepfile.cxx @@ -13,6 +13,7 @@ #include "cmGccDepfileReader.h" #include "cmGccDepfileReaderTypes.h" +#include "cmLocalGenerator.h" #include "cmSystemTools.h" namespace { @@ -33,8 +34,11 @@ void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename) } } -void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content) +void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg, + const cmGccDepfileContent& content) { + const auto& binDir = lg.GetBinaryDirectory(); + for (auto const& dep : content) { bool first = true; for (auto const& rule : dep.rules) { @@ -42,19 +46,32 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content) fout << " \\\n "; } first = false; - WriteFilenameGcc(fout, rule); + WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, rule)); } fout << ':'; for (auto const& path : dep.paths) { fout << " \\\n "; - WriteFilenameGcc(fout, path); + WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, path)); } fout << '\n'; } } -void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content) +// tlog format : always windows paths on Windows regardless the generator +std::string ConvertToTLogOutputPath(const std::string& path) { +#if defined(_WIN32) && !defined(__CYGWIN__) + return cmSystemTools::ConvertToWindowsOutputPath(path); +#else + return cmSystemTools::ConvertToOutputPath(path); +#endif +} + +void WriteVsTlog(cmsys::ofstream& fout, const cmLocalGenerator& lg, + const cmGccDepfileContent& content) +{ + const auto& binDir = lg.GetBinaryDirectory(); + for (auto const& dep : content) { fout << '^'; bool first = true; @@ -63,22 +80,26 @@ void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content) fout << '|'; } first = false; - fout << cmSystemTools::ConvertToOutputPath(rule); + fout << ConvertToTLogOutputPath( + lg.MaybeConvertToRelativePath(binDir, rule)); } fout << "\r\n"; for (auto const& path : dep.paths) { - fout << cmSystemTools::ConvertToOutputPath(path) << "\r\n"; + fout << ConvertToTLogOutputPath( + lg.MaybeConvertToRelativePath(binDir, path)) + << "\r\n"; } } } } -bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix, +bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, const std::string& infile, const std::string& outfile) { cmGccDepfileContent content; if (cmSystemTools::FileExists(infile)) { - auto result = cmReadGccDepfile(infile.c_str(), prefix); + auto result = + cmReadGccDepfile(infile.c_str(), lg.GetCurrentBinaryDirectory()); if (!result) { return false; } @@ -91,10 +112,10 @@ bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix, } switch (format) { case cmDepfileFormat::GccDepfile: - WriteGccDepfile(fout, content); + WriteGccDepfile(fout, lg, content); break; case cmDepfileFormat::VsTlog: - WriteVsTlog(fout, content); + WriteVsTlog(fout, lg, content); break; } return true; diff --git a/Source/cmTransformDepfile.h b/Source/cmTransformDepfile.h index 792c1aa..c43a45f 100644 --- a/Source/cmTransformDepfile.h +++ b/Source/cmTransformDepfile.h @@ -10,5 +10,7 @@ enum class cmDepfileFormat VsTlog, }; -bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix, +class cmLocalGenerator; + +bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, const std::string& infile, const std::string& outfile); diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 851205e..f6d8901 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1522,20 +1522,42 @@ int cmcmd::ExecuteCMakeCommand(std::vector const& args, #endif // Internal depfile transformation - if (args[1] == "cmake_transform_depfile" && args.size() == 6) { + if (args[1] == "cmake_transform_depfile" && args.size() == 10) { auto format = cmDepfileFormat::GccDepfile; - if (args[2] == "gccdepfile") { + if (args[3] == "gccdepfile") { format = cmDepfileFormat::GccDepfile; - } else if (args[2] == "vstlog") { + } else if (args[3] == "vstlog") { format = cmDepfileFormat::VsTlog; } else { return 1; } - std::string prefix = args[3]; - if (prefix == "./") { - prefix.clear(); + // Create a cmake object instance to process dependencies. + // All we need is the `set` command. + cmake cm(cmake::RoleScript, cmState::Unknown); + std::string homeDir; + std::string startDir; + std::string homeOutDir; + std::string startOutDir; + homeDir = cmSystemTools::CollapseFullPath(args[4]); + startDir = cmSystemTools::CollapseFullPath(args[5]); + homeOutDir = cmSystemTools::CollapseFullPath(args[6]); + startOutDir = cmSystemTools::CollapseFullPath(args[7]); + cm.SetHomeDirectory(homeDir); + cm.SetHomeOutputDirectory(homeOutDir); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); + if (auto ggd = cm.CreateGlobalGenerator(args[2])) { + cm.SetGlobalGenerator(std::move(ggd)); + cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); + snapshot.GetDirectory().SetCurrentBinary(startOutDir); + snapshot.GetDirectory().SetCurrentSource(startDir); + snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str()); + snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str()); + cmMakefile mf(cm.GetGlobalGenerator(), snapshot); + auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); + + return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2; } - return cmTransformDepfile(format, prefix, args[4], args[5]) ? 0 : 1; + return 1; } } diff --git a/Tests/RunCMake/BuildDepends/CMakeLists.txt b/Tests/RunCMake/BuildDepends/CMakeLists.txt index 74b3ff8..99f238b 100644 --- a/Tests/RunCMake/BuildDepends/CMakeLists.txt +++ b/Tests/RunCMake/BuildDepends/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 3.3) project(${RunCMake_TEST} NONE) -include(${RunCMake_TEST}.cmake) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake index 6ac1291..01eac91 100644 --- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake +++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake @@ -4,7 +4,7 @@ enable_language(C) add_custom_command( OUTPUT topcc.c DEPFILE topcc.c.d - COMMAND ${CMAKE_COMMAND} -DOUTFILE=topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" + COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" ) add_custom_target(topcc ALL DEPENDS topcc.c) diff --git a/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt b/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt index 06db47c..f131751 100644 --- a/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt +++ b/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0116 NEW) add_custom_command( OUTPUT subcc.c DEPFILE subcc.c.d - COMMAND ${CMAKE_COMMAND} -DOUTFILE=subcc.c -DINFILE=subccdep.txt -DDEPFILE=subcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/../WriteDepfile.cmake" + COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/subcc.c -DINFILE=subccdep.txt -DDEPFILE=subcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/../WriteDepfile.cmake" ) add_custom_target(subcc ALL DEPENDS subcc.c) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 540a718..d1122d0 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -796,7 +796,10 @@ add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} add_RunCMake_test("UnityBuild") add_RunCMake_test(CMakePresets -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA}) -add_RunCMake_test(TransformDepfile) + +if(${CMAKE_GENERATOR} MATCHES "Make|Ninja") + add_RunCMake_test(TransformDepfile) +endif() if(WIN32) add_RunCMake_test(Win32GenEx) diff --git a/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake b/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake index cb75eb0..9a38b95 100644 --- a/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake +++ b/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake @@ -3,11 +3,11 @@ include(RunCMake) function(run_transform_depfile name) set(RunCMake-check-file gccdepfile.cmake) run_cmake_command(${name}-gcc - ${CMAKE_COMMAND} -E cmake_transform_depfile gccdepfile ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.d + ${CMAKE_COMMAND} -E cmake_transform_depfile "${RunCMake_GENERATOR}" gccdepfile "${RunCMake_SOURCE_DIR}" "${RunCMake_SOURCE_DIR}/subdir" "${RunCMake_BINARY_DIR}" "${RunCMake_BINARY_DIR}/subdir" "${CMAKE_CURRENT_LIST_DIR}/${name}.d" out.d ) set(RunCMake-check-file vstlog.cmake) run_cmake_command(${name}-tlog - ${CMAKE_COMMAND} -E cmake_transform_depfile vstlog ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.tlog + ${CMAKE_COMMAND} -E cmake_transform_depfile "${RunCMake_GENERATOR}" vstlog "${RunCMake_SOURCE_DIR}" "${RunCMake_SOURCE_DIR}/subdir" "${RunCMake_BINARY_DIR}" "${RunCMake_BINARY_DIR}/subdir" "${CMAKE_CURRENT_LIST_DIR}/${name}.d" out.tlog ) endfunction() diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.d.txt b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt index 58770f2..fbdecc0 100644 --- a/Tests/RunCMake/TransformDepfile/deps-unix.d.txt +++ b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt @@ -1,8 +1,8 @@ -../out1 \ +subdir/out1 \ /home/build/out2: \ - ../in1 \ + subdir/in1 \ /home/build/in2 -../out3 \ +subdir/out3 \ /home/build/out4: \ - ../in3 \ + subdir/in3 \ /home/build/in4 diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt b/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt index 2a26edf..70bac5d 100644 --- a/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt +++ b/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt @@ -1,6 +1,6 @@ -^../out1|/home/build/out2 -../in1 +^subdir/out1|/home/build/out2 +subdir/in1 /home/build/in2 -^../out3|/home/build/out4 -../in3 +^subdir/out3|/home/build/out4 +subdir/in3 /home/build/in4 diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.d.txt b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt index 47b3ebf..e09ae37 100644 --- a/Tests/RunCMake/TransformDepfile/deps-windows.d.txt +++ b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt @@ -1,8 +1,8 @@ -../out1 \ +subdir/out1 \ C:/build/out2: \ - ../in1 \ + subdir/in1 \ C:/build/in2 -../out3 \ +subdir/out3 \ C:/build/out4: \ - ../in3 \ + subdir/in3 \ C:/build/in4 diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt b/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt index 1e6024d..09f9e97 100644 --- a/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt +++ b/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt @@ -1,6 +1,6 @@ -^..\out1|C:\build\out2 -..\in1 +^subdir\out1|C:\build\out2 +subdir\in1 C:\build\in2 -^..\out3|C:\build\out4 -..\in3 +^subdir\out3|C:\build\out4 +subdir\in3 C:\build\in4 diff --git a/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt b/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt index d00491f..0cfbf08 100644 --- a/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt +++ b/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt @@ -1 +1 @@ -1 +2 diff --git a/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt b/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt index d00491f..0cfbf08 100644 --- a/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt +++ b/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt @@ -1 +1 @@ -1 +2 -- cgit v0.12