[clang] [clang] Absoultify paths in dependency file output (PR #117458)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Dec 31 15:46:29 PST 2024
https://github.com/xtexChooser updated https://github.com/llvm/llvm-project/pull/117458
>From a4997209062fe1e2b23dcbe88ed2cdcdf8c9a0db Mon Sep 17 00:00:00 2001
From: Bingwu Zhang <xtex at aosc.io>
Date: Sun, 24 Nov 2024 07:06:35 +0800
Subject: [PATCH] [clang] Absoultify paths in dependency file output
This fixes #117438.
If paths in dependency file are not absoulte, make (or ninja) will
canonicalize them.
While their canonicalization does not involves symbolic links
expansion (for IO performance concerns), leaving a
non-absolute path in dependency file may lead to unexpected
canonicalization.
For example, '/a/../b', where '/a' is a symlink to '/c/d', it should be
'/c/b' but make (and ninja) canonicalizes it as '/b', and fails for file
not found.
Signed-off-by: Bingwu Zhang <xtex at aosc.io>
---
clang/include/clang/Frontend/Utils.h | 1 +
clang/lib/Frontend/DependencyFile.cpp | 22 +++++++++++++++----
clang/test/Frontend/dependency-gen-symlink.c | 2 +-
.../dependency-gen-windows-duplicates.c | 2 +-
clang/test/VFS/external-names.c | 2 +-
5 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index 604e42067a3f1e..8ed17179c9824b 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -120,6 +120,7 @@ class DependencyFileGenerator : public DependencyCollector {
private:
void outputDependencyFile(DiagnosticsEngine &Diags);
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
std::string OutputFile;
std::vector<std::string> Targets;
bool IncludeSystemHeaders;
diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp
index 528eae2c5283ea..8a36d835d82b3f 100644
--- a/clang/lib/Frontend/DependencyFile.cpp
+++ b/clang/lib/Frontend/DependencyFile.cpp
@@ -10,11 +10,11 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Frontend/Utils.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/PPCallbacks.h"
@@ -23,8 +23,10 @@
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
+#include <system_error>
using namespace clang;
@@ -236,6 +238,7 @@ void DependencyFileGenerator::attachToPreprocessor(Preprocessor &PP) {
PP.SetSuppressIncludeNotFoundError(true);
DependencyCollector::attachToPreprocessor(PP);
+ FS = PP.getFileManager().getVirtualFileSystemPtr();
}
bool DependencyFileGenerator::sawDependency(StringRef Filename, bool FromModule,
@@ -312,11 +315,22 @@ void DependencyFileGenerator::finishedMainFile(DiagnosticsEngine &Diags) {
/// https://msdn.microsoft.com/en-us/library/dd9y37ha.aspx for NMake info,
/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
/// for Windows file-naming info.
-static void PrintFilename(raw_ostream &OS, StringRef Filename,
+static void printFilename(raw_ostream &OS, llvm::vfs::FileSystem *FS,
+ StringRef Filename,
DependencyOutputFormat OutputFormat) {
// Convert filename to platform native path
llvm::SmallString<256> NativePath;
llvm::sys::path::native(Filename.str(), NativePath);
+ // Resolve absolute path. Make and Ninja canonicalize paths
+ // without checking for symbolic links in the path, for performance concerns.
+ // If there is something like `/bin/../lib64` -> `/usr/lib64`
+ // (where `/bin` links to `/usr/bin`), Make will see them as `/lib64`.
+ if (FS != nullptr && llvm::sys::path::is_absolute(NativePath)) {
+ llvm::SmallString<256> NativePathTmp = NativePath;
+ std::error_code EC = FS->getRealPath(NativePathTmp, NativePath);
+ if (EC)
+ NativePath = NativePathTmp;
+ }
if (OutputFormat == DependencyOutputFormat::NMake) {
// Add quotes if needed. These are the characters listed as "special" to
@@ -400,7 +414,7 @@ void DependencyFileGenerator::outputDependencyFile(llvm::raw_ostream &OS) {
Columns = 2;
}
OS << ' ';
- PrintFilename(OS, File, OutputFormat);
+ printFilename(OS, FS.get(), File, OutputFormat);
Columns += N + 1;
}
OS << '\n';
@@ -411,7 +425,7 @@ void DependencyFileGenerator::outputDependencyFile(llvm::raw_ostream &OS) {
for (auto I = Files.begin(), E = Files.end(); I != E; ++I) {
if (Index++ == InputFileIndex)
continue;
- PrintFilename(OS, *I, OutputFormat);
+ printFilename(OS, FS.get(), *I, OutputFormat);
OS << ":\n";
}
}
diff --git a/clang/test/Frontend/dependency-gen-symlink.c b/clang/test/Frontend/dependency-gen-symlink.c
index 2fa339ad2abf24..15664a46b90c85 100644
--- a/clang/test/Frontend/dependency-gen-symlink.c
+++ b/clang/test/Frontend/dependency-gen-symlink.c
@@ -15,7 +15,7 @@
// CHECK: dependency-gen-symlink.c.o
// CHECK: dependency-gen-symlink.c
// CHECK: a/header.h
-// CHECK: b/header.h
+// CHECK-NOT: b/header.h
// CHECK-NOT: with-header-guard.h
#include "a/header.h"
#include "b/header.h"
diff --git a/clang/test/Frontend/dependency-gen-windows-duplicates.c b/clang/test/Frontend/dependency-gen-windows-duplicates.c
index abd351377dc333..0ecc23226fb9c8 100644
--- a/clang/test/Frontend/dependency-gen-windows-duplicates.c
+++ b/clang/test/Frontend/dependency-gen-windows-duplicates.c
@@ -9,7 +9,7 @@
// RUN: %clang -MD -MF - %t.dir/test.c -fsyntax-only -I %t.dir/subdir | FileCheck %s
// CHECK: test.o:
// CHECK-NEXT: \test.c
-// CHECK-NEXT: \SubDir\X.h
+// CHECK-NEXT: \subdir\x.h
// File x.h must appear only once (case insensitive check).
// CHECK-NOT: {{\\|/}}{{x|X}}.{{h|H}}
diff --git a/clang/test/VFS/external-names.c b/clang/test/VFS/external-names.c
index 5b7c443b36e564..dd0b5eb501840e 100644
--- a/clang/test/VFS/external-names.c
+++ b/clang/test/VFS/external-names.c
@@ -47,4 +47,4 @@
// RUN: %clang_cc1 -D REINCLUDE -I %t -ivfsoverlay %t.yaml -Eonly %s -MTfoo -dependency-file %t.dep
// RUN: cat %t.dep | FileCheck --check-prefix=CHECK-DEP %s
-// CHECK-DEP-NOT: Inputs
+// CHECK-DEP: Inputs{{..?}}external-names.h
More information about the cfe-commits
mailing list