diff options
author | Arthur Eubanks <aeubanks@google.com> | 2023-04-25 13:16:01 -0700 |
---|---|---|
committer | Arthur Eubanks <aeubanks@google.com> | 2023-05-01 12:44:52 -0700 |
commit | 578a4716f549167165a2ec3bac89c86706136d4e (patch) | |
tree | 33a11827e328c043c71fe764cb78e7dba696d909 /clang/lib/Frontend/DependencyFile.cpp | |
parent | 17a8e245703a375c53c9ee4e3f6ed11b6869d771 (diff) | |
download | llvm-578a4716f549167165a2ec3bac89c86706136d4e.zip llvm-578a4716f549167165a2ec3bac89c86706136d4e.tar.gz llvm-578a4716f549167165a2ec3bac89c86706136d4e.tar.bz2 |
Reland [clang] Canonicalize system headers in dependency file when -canonical-prefixes
Clang was writing paths to the dependency file that don't exist when using a sysroot with symlinks, causing everything to get rebuilt every time. This is reproducible on Linux by creating a symlink to '/', using that as the sysroot, and trying to build something with ninja that includes the C++ stdlib (e.g. a typical build of LLVM).
This fixes https://github.com/ninja-build/ninja/issues/1330 and somewhat matches gcc.
gcc canonicalizes system headers in dependency files under a -f[no-]canonical-system-headers, but it makes more sense to look at -canonical-prefixes.
D37954 was a previous attempt at this.
Fixed use of %T instead of %t in test, causing bots to fail the test on the initial commit.
Reviewed By: hans
Differential Revision: https://reviews.llvm.org/D149187
Diffstat (limited to 'clang/lib/Frontend/DependencyFile.cpp')
-rw-r--r-- | clang/lib/Frontend/DependencyFile.cpp | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/clang/lib/Frontend/DependencyFile.cpp b/clang/lib/Frontend/DependencyFile.cpp index fe4218b..44268e7 100644 --- a/clang/lib/Frontend/DependencyFile.cpp +++ b/clang/lib/Frontend/DependencyFile.cpp @@ -49,6 +49,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks { DepCollector.maybeAddDependency( llvm::sys::path::remove_leading_dotslash(*Filename), /*FromModule*/ false, isSystem(FileType), /*IsModuleFile*/ false, + &PP.getFileManager(), /*IsMissing*/ false); } @@ -56,9 +57,11 @@ struct DepCollectorPPCallbacks : public PPCallbacks { SrcMgr::CharacteristicKind FileType) override { StringRef Filename = llvm::sys::path::remove_leading_dotslash(SkippedFile.getName()); - DepCollector.maybeAddDependency(Filename, /*FromModule=*/false, + DepCollector.maybeAddDependency(Filename, + /*FromModule=*/false, /*IsSystem=*/isSystem(FileType), /*IsModuleFile=*/false, + &PP.getFileManager(), /*IsMissing=*/false); } @@ -69,9 +72,12 @@ struct DepCollectorPPCallbacks : public PPCallbacks { StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override { if (!File) - DepCollector.maybeAddDependency(FileName, /*FromModule*/false, - /*IsSystem*/false, /*IsModuleFile*/false, - /*IsMissing*/true); + DepCollector.maybeAddDependency(FileName, + /*FromModule*/ false, + /*IsSystem*/ false, + /*IsModuleFile*/ false, + &PP.getFileManager(), + /*IsMissing*/ true); // Files that actually exist are handled by FileChanged. } @@ -82,9 +88,11 @@ struct DepCollectorPPCallbacks : public PPCallbacks { return; StringRef Filename = llvm::sys::path::remove_leading_dotslash(File->getName()); - DepCollector.maybeAddDependency(Filename, /*FromModule=*/false, + DepCollector.maybeAddDependency(Filename, + /*FromModule=*/false, /*IsSystem=*/isSystem(FileType), /*IsModuleFile=*/false, + &PP.getFileManager(), /*IsMissing=*/false); } @@ -100,10 +108,12 @@ struct DepCollectorMMCallbacks : public ModuleMapCallbacks { void moduleMapFileRead(SourceLocation Loc, const FileEntry &Entry, bool IsSystem) override { StringRef Filename = Entry.getName(); - DepCollector.maybeAddDependency(Filename, /*FromModule*/false, - /*IsSystem*/IsSystem, - /*IsModuleFile*/false, - /*IsMissing*/false); + DepCollector.maybeAddDependency(Filename, + /*FromModule*/ false, + /*IsSystem*/ IsSystem, + /*IsModuleFile*/ false, + /*FileMgr*/ nullptr, + /*IsMissing*/ false); } }; @@ -118,9 +128,11 @@ struct DepCollectorASTListener : public ASTReaderListener { } void visitModuleFile(StringRef Filename, serialization::ModuleKind Kind) override { - DepCollector.maybeAddDependency(Filename, /*FromModule*/true, - /*IsSystem*/false, /*IsModuleFile*/true, - /*IsMissing*/false); + DepCollector.maybeAddDependency(Filename, + /*FromModule*/ true, + /*IsSystem*/ false, /*IsModuleFile*/ true, + /*FileMgr*/ nullptr, + /*IsMissing*/ false); } bool visitInputFile(StringRef Filename, bool IsSystem, bool IsOverridden, bool IsExplicitModule) override { @@ -132,8 +144,9 @@ struct DepCollectorASTListener : public ASTReaderListener { if (auto FE = FileMgr.getOptionalFileRef(Filename)) Filename = FE->getName(); - DepCollector.maybeAddDependency(Filename, /*FromModule*/true, IsSystem, - /*IsModuleFile*/false, /*IsMissing*/false); + DepCollector.maybeAddDependency(Filename, /*FromModule*/ true, IsSystem, + /*IsModuleFile*/ false, /*FileMgr*/ nullptr, + /*IsMissing*/ false); return true; } }; @@ -142,9 +155,15 @@ struct DepCollectorASTListener : public ASTReaderListener { void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, + FileManager *FileMgr, bool IsMissing) { - if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing)) + if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing)) { + if (IsSystem && FileMgr && shouldCanonicalizeSystemDependencies()) { + if (auto F = FileMgr->getFile(Filename)) + Filename = FileMgr->getCanonicalName(*F); + } addDependency(Filename); + } } bool DependencyCollector::addDependency(StringRef Filename) { @@ -192,6 +211,7 @@ DependencyFileGenerator::DependencyFileGenerator( const DependencyOutputOptions &Opts) : OutputFile(Opts.OutputFile), Targets(Opts.Targets), IncludeSystemHeaders(Opts.IncludeSystemHeaders), + CanonicalSystemHeaders(Opts.CanonicalSystemHeaders), PhonyTarget(Opts.UsePhonyTargets), AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), SeenMissingHeader(false), IncludeModuleFiles(Opts.IncludeModuleFiles), |