mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-13 17:47:49 +08:00
Ninja: add_custom_command(DEPFILE): Ensure dependencies consistency
Fixes: #21694
This commit is contained in:
@@ -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());
|
||||
|
||||
|
@@ -97,17 +97,8 @@ bool cmDependsCompiler::CheckDependencies(
|
||||
|
||||
std::vector<std::string> 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;
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ cm::optional<cmGccDepfileContent> 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<cmGccDepfileContent> 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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -1522,20 +1522,42 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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()
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -1 +1 @@
|
||||
1
|
||||
2
|
||||
|
@@ -1 +1 @@
|
||||
1
|
||||
2
|
||||
|
Reference in New Issue
Block a user