1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-06-09 07:20:19 +08:00
CMake/Source/cmGccDepfileReader.cxx
Marc Chevrier 6a6efdcaed Makefiles: Normalize compiler-generated depfile paths
Even though Makefile generators pass source files and include
directories by absolute path to the compiler, the compiler may generate
depfile paths relative to the current working directory.  For example,
`ccache` with `CCACHE_BASEDIR` may transform paths this way.  When
reading a depfile, convert relative dependencies to absolute paths
before placing them in `compiler_depend.make`, which is later evaluated
in the top-level build directory.

Fixes: #22364
2021-07-02 09:24:57 -04:00

49 lines
1.4 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGccDepfileReader.h"
#include <type_traits>
#include <utility>
#include <vector>
#include <cm/optional>
#include "cmGccDepfileLexerHelper.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cm::optional<cmGccDepfileContent> cmReadGccDepfile(
const char* filePath, const std::string& prefix,
GccDepfilePrependPaths prependPaths)
{
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 (prependPaths == GccDepfilePrependPaths::All && !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 (!prefix.empty() && !cmSystemTools::FileIsFullPath(path)) {
path = cmStrCat(prefix, '/', path);
}
if (cmSystemTools::FileIsFullPath(path)) {
path = cmSystemTools::CollapseFullPath(path);
}
cmSystemTools::ConvertToLongPath(path);
}
}
return deps;
}