Merge topic 'makefiles-compiler-deps'

bb64ea5741 Makefiles: ensure transparent switch between dependencies strategies
8ec7408d74 Makefile dependencies: ensure long paths are used on Windows

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5655
This commit is contained in:
Brad King 2021-01-11 16:28:52 +00:00 committed by Kitware Robot
commit 06dfa5a7b6
6 changed files with 83 additions and 48 deletions

View File

@ -12,40 +12,33 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath)
{
cmGccDepfileLexerHelper helper;
if (helper.readFile(filePath)) {
return cm::make_optional(std::move(helper).extractContent());
}
return cm::nullopt;
}
cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath,
const std::string& prefix)
{
auto deps = cmReadGccDepfile(filePath);
if (prefix.empty() || !deps) {
return deps;
cmGccDepfileLexerHelper helper;
if (!helper.readFile(filePath)) {
return cm::nullopt;
}
auto deps = cm::make_optional(std::move(helper).extractContent());
for (auto& dep : *deps) {
for (auto& rule : dep.rules) {
if (!cmSystemTools::FileIsFullPath(rule)) {
if (!prefix.empty() && !cmSystemTools::FileIsFullPath(rule)) {
rule = cmStrCat(prefix, rule);
}
if (cmSystemTools::FileIsFullPath(rule)) {
rule = cmSystemTools::CollapseFullPath(rule);
}
cmSystemTools::ConvertToLongPath(rule);
}
for (auto& path : dep.paths) {
if (!cmSystemTools::FileIsFullPath(path)) {
if (!prefix.empty() && !cmSystemTools::FileIsFullPath(path)) {
path = cmStrCat(prefix, path);
}
if (cmSystemTools::FileIsFullPath(path)) {
path = cmSystemTools::CollapseFullPath(path);
}
cmSystemTools::ConvertToLongPath(path);
}
}

View File

@ -8,10 +8,8 @@
#include "cmGccDepfileReaderTypes.h"
cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath);
/*
* Read dependencies file and append prefix to all relative paths
*/
cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath,
const std::string& prefix);
cm::optional<cmGccDepfileContent> cmReadGccDepfile(
const char* filePath, const std::string& prefix = {});

View File

@ -345,27 +345,51 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
this->LocalGenerator->GetBinaryDirectory(), compilerDependFile))
<< "\n\n";
if (!cmSystemTools::FileExists(compilerDependFile)) {
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(
compilerDependFile, false,
this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# Empty compiler generated dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
<< "# This may be replaced when dependencies are built.\n";
}
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(
compilerDependFile, false, this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# Empty compiler generated dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
<< "# This may be replaced when dependencies are built.\n";
// remove internal dependency file
cmSystemTools::RemoveFile(
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.internal"));
std::string compilerDependTimestamp =
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts");
if (!cmSystemTools::FileExists(compilerDependTimestamp)) {
// Write a dependency timestamp file.
cmGeneratedFileStream depFileStream(
cmGeneratedFileStream timestampFileStream(
compilerDependTimestamp, false,
this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# CMAKE generated file: DO NOT EDIT!\n"
<< "# Timestamp file for compiler generated dependencies "
"management for "
<< this->GeneratorTarget->GetName() << ".\n";
timestampFileStream
<< "# CMAKE generated file: DO NOT EDIT!\n"
<< "# Timestamp file for compiler generated dependencies "
"management for "
<< this->GeneratorTarget->GetName() << ".\n";
}
// deactivate no longer needed legacy dependency files
// Write an empty dependency file.
cmGeneratedFileStream legacyDepFileStream(
dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
legacyDepFileStream
<< "# Empty dependencies file for " << this->GeneratorTarget->GetName()
<< ".\n"
<< "# This may be replaced when dependencies are built.\n";
// remove internal dependency file
cmSystemTools::RemoveFile(
cmStrCat(this->TargetBuildDirectoryFull, "/depend.internal"));
} else {
// make sure the depend file exists
if (!cmSystemTools::FileExists(dependFileNameFull)) {
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(
dependFileNameFull, false,
this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# Empty dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
<< "# This may be replaced when dependencies are built.\n";
}
}
@ -381,16 +405,6 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
<< "\n\n";
}
// make sure the depend file exists
if (!cmSystemTools::FileExists(dependFileNameFull)) {
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(
dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# Empty dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
<< "# This may be replaced when dependencies are built.\n";
}
// Open the flags file. This should be copy-if-different because the
// rules may depend on this file itself.
this->FlagFileNameFull =
@ -855,6 +869,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
shellDependencyFile = this->LocalGenerator->ConvertToOutputFormat(
depFile, cmOutputConverter::SHELL);
vars.DependencyFile = shellDependencyFile.c_str();
this->CleanFiles.insert(depFile);
dependencyTimestamp = this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetBinaryDirectory(),

View File

@ -1255,6 +1255,30 @@ void cmSystemTools::ConvertToOutputSlashes(std::string& path)
#endif
}
void cmSystemTools::ConvertToLongPath(std::string& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
// Try to convert path to a long path only if the path contains character '~'
if (path.find('~') == std::string::npos) {
return;
}
std::wstring wPath = cmsys::Encoding::ToWide(path);
DWORD ret = GetLongPathNameW(wPath.c_str(), nullptr, 0);
std::vector<wchar_t> buffer(ret);
if (ret != 0) {
ret = GetLongPathNameW(wPath.c_str(), buffer.data(),
static_cast<DWORD>(buffer.size()));
}
if (ret != 0) {
path = cmsys::Encoding::ToNarrow(buffer.data());
}
#else
static_cast<void>(path);
#endif
}
std::string cmSystemTools::ConvertToRunCommandPath(const std::string& path)
{
#if defined(_WIN32) && !defined(__CYGWIN__)

View File

@ -287,6 +287,12 @@ public:
// running cmake needs paths to be in its format
static std::string ConvertToRunCommandPath(const std::string& path);
/**
* For windows computes the long path for the given path,
* For Unix, it is a noop
*/
static void ConvertToLongPath(std::string& path);
/** compute the relative path from local to remote. local must
be a directory. remote can be a file or a directory.
Both remote and local must be full paths. Basically, if

View File

@ -231,11 +231,10 @@ private:
bool ProcessLine() override
{
if (cmHasPrefix(this->Line, this->IncludePrefix)) {
this->DepFile << cmCMakePath(
cmTrimWhitespace(this->Line.c_str() +
this->IncludePrefix.size()))
.GenericString()
<< std::endl;
auto path =
cmTrimWhitespace(this->Line.c_str() + this->IncludePrefix.size());
cmSystemTools::ConvertToLongPath(path);
this->DepFile << cmCMakePath(path).GenericString() << std::endl;
} else {
this->Output << this->Line << std::endl << std::flush;
}