r316193 - Try to shorten system header paths when using -MD depfiles

Peter Wu via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 19 16:53:27 PDT 2017


Author: lekensteyn
Date: Thu Oct 19 16:53:27 2017
New Revision: 316193

URL: http://llvm.org/viewvc/llvm-project?rev=316193&view=rev
Log:
Try to shorten system header paths when using -MD depfiles

GCC tries to shorten system headers in depfiles using its real path
(resolving components like ".." and following symlinks). Mimic this
feature to ensure that the Ninja build tool detects the correct
dependencies when a symlink changes directory levels, see
https://github.com/ninja-build/ninja/issues/1330

An option to disable this feature is added in case "these changed header
paths may conflict with some compilation environments", see
https://gcc.gnu.org/ml/gcc-patches/2012-09/msg00287.html

Note that the original feature request for GCC
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52974) also included paths
preprocessed output (-E) and diagnostics. That is not implemented now
since I am not sure if it breaks something else.

Differential Revision: https://reviews.llvm.org/D37954

Added:
    cfe/trunk/test/Preprocessor/dependencies-realpath.c   (with props)
Modified:
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h
    cfe/trunk/lib/Driver/Job.cpp
    cfe/trunk/lib/Driver/ToolChains/Clang.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/DependencyFile.cpp
    cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=316193&r1=316192&r2=316193&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Thu Oct 19 16:53:27 2017
@@ -384,6 +384,11 @@ def MT : JoinedOrSeparate<["-"], "MT">,
     HelpText<"Specify name of main file output in depfile">;
 def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>,
     HelpText<"Use NMake/Jom format for the depfile">;
+def fno_canonical_system_headers : Flag<["-"], "fno-canonical-system-headers">,
+    Group<M_Group>, Flags<[CC1Option]>,
+    HelpText<"Do not shorten system header paths in depfiles">;
+def fcanonical_system_headers : Flag<["-"], "fcanonical-system-headers">,
+    Group<M_Group>;
 def Mach : Flag<["-"], "Mach">, Group<Link_Group>;
 def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;
 def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option, HelpHidden]>;

Modified: cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h?rev=316193&r1=316192&r2=316193&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/DependencyOutputOptions.h Thu Oct 19 16:53:27 2017
@@ -30,6 +30,8 @@ public:
   unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
   unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
   unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
+  unsigned CanonicalSystemHeaders : 1; ///< Try to output a shorter path for
+                                       /// system header dependencies.
 
   /// The format for the dependency file.
   DependencyOutputFormat OutputFormat;
@@ -67,6 +69,7 @@ public:
     AddMissingHeaderDeps = 0;
     PrintShowIncludes = 0;
     IncludeModuleFiles = 0;
+    CanonicalSystemHeaders = 1;
     OutputFormat = DependencyOutputFormat::Make;
   }
 };

Modified: cfe/trunk/lib/Driver/Job.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Job.cpp?rev=316193&r1=316192&r2=316193&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Job.cpp (original)
+++ cfe/trunk/lib/Driver/Job.cpp Thu Oct 19 16:53:27 2017
@@ -73,8 +73,8 @@ static bool skipArgs(const char *Flag, b
 
   // These flags are all of the form -Flag and have no second argument.
   ShouldSkip = llvm::StringSwitch<bool>(Flag)
-    .Cases("-M", "-MM", "-MG", "-MP", "-MD", true)
-    .Case("-MMD", true)
+    .Cases("-M", "-MM", "-MG", "-MP", "-MD", "-MMD", true)
+    .Cases("-fno-canonical-system-headers", "-fcanonical-system-headers", true)
     .Default(false);
 
   // Match found.

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=316193&r1=316192&r2=316193&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Thu Oct 19 16:53:27 2017
@@ -964,6 +964,13 @@ void Clang::AddPreprocessingOptions(Comp
   Args.AddLastArg(CmdArgs, options::OPT_C);
   Args.AddLastArg(CmdArgs, options::OPT_CC);
 
+  if (Arg *A = Args.getLastArg(options::OPT_fno_canonical_system_headers,
+                               options::OPT_fcanonical_system_headers)) {
+    if (A->getOption().matches(options::OPT_fno_canonical_system_headers)) {
+      CmdArgs.push_back("-fno-canonical-system-headers");
+    }
+  }
+
   // Handle dependency file generation.
   if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
       (A = Args.getLastArg(options::OPT_MD)) ||

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=316193&r1=316192&r2=316193&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu Oct 19 16:53:27 2017
@@ -1002,6 +1002,7 @@ static void ParseDependencyOutputArgs(De
   Opts.Targets = Args.getAllArgValues(OPT_MT);
   Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
   Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
+  Opts.CanonicalSystemHeaders = !Args.hasArg(OPT_fno_canonical_system_headers);
   Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
   Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
   Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);

Modified: cfe/trunk/lib/Frontend/DependencyFile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DependencyFile.cpp?rev=316193&r1=316192&r2=316193&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/DependencyFile.cpp (original)
+++ cfe/trunk/lib/Frontend/DependencyFile.cpp Thu Oct 19 16:53:27 2017
@@ -161,6 +161,7 @@ class DFGImpl : public PPCallbacks {
   bool AddMissingHeaderDeps;
   bool SeenMissingHeader;
   bool IncludeModuleFiles;
+  bool CanonicalSystemHeaders;
   DependencyOutputFormat OutputFormat;
 
 private:
@@ -176,6 +177,7 @@ public:
       AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
       SeenMissingHeader(false),
       IncludeModuleFiles(Opts.IncludeModuleFiles),
+      CanonicalSystemHeaders(Opts.CanonicalSystemHeaders),
       OutputFormat(Opts.OutputFormat) {
     for (const auto &ExtraDep : Opts.ExtraDeps) {
       AddFilename(ExtraDep);
@@ -288,6 +290,15 @@ void DFGImpl::FileChanged(SourceLocation
   if (!FileMatchesDepCriteria(Filename.data(), FileType))
     return;
 
+  // Try to shorten system header paths like GCC does (unless
+  // -fno-canonical-system-headers is given).
+  if (CanonicalSystemHeaders && isSystem(FileType)) {
+    StringRef RealPath = FE->tryGetRealPathName();
+    if (!RealPath.empty() && RealPath.size() < Filename.size()) {
+      Filename = RealPath;
+    }
+  }
+
   AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
 }
 

Modified: cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp?rev=316193&r1=316192&r2=316193&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp (original)
+++ cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp Thu Oct 19 16:53:27 2017
@@ -58,7 +58,9 @@ ArgumentsAdjuster getClangStripDependenc
       StringRef Arg = Args[i];
       // All dependency-file options begin with -M. These include -MM,
       // -MF, -MG, -MP, -MT, -MQ, -MD, and -MMD.
-      if (!Arg.startswith("-M"))
+      // The exception is -f[no-]canonical-system-headers.
+      if (!Arg.startswith("-M") && Arg != "-fno-canonical-system-headers" &&
+          Arg != "-fcanonical-system-headers")
         AdjustedArgs.push_back(Args[i]);
 
       if ((Arg == "-MF") || (Arg == "-MT") || (Arg == "-MQ") ||

Added: cfe/trunk/test/Preprocessor/dependencies-realpath.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/dependencies-realpath.c?rev=316193&view=auto
==============================================================================
--- cfe/trunk/test/Preprocessor/dependencies-realpath.c (added)
+++ cfe/trunk/test/Preprocessor/dependencies-realpath.c Thu Oct 19 16:53:27 2017
@@ -0,0 +1,33 @@
+// RUN: mkdir -p %t/sub/dir
+// RUN: echo > %t/sub/empty.h
+
+// Test that system header paths are expanded
+//
+// RUN: %clang -fsyntax-only -MD -MF %t.d -MT foo %s -isystem %t/sub/dir/..
+// RUN: FileCheck -check-prefix=TEST1 %s < %t.d
+// TEST1: foo:
+// TEST1: sub{{/|\\}}empty.h
+
+// Test that system header paths are not expanded to a longer form
+//
+// RUN: cd %t && %clang -fsyntax-only -MD -MF %t.d -MT foo %s -isystem sub/dir/..
+// RUN: FileCheck -check-prefix=TEST2 %s < %t.d
+// TEST2: foo:
+// TEST2: sub/dir/..{{/|\\}}empty.h
+
+// Test that user header paths are not expanded
+//
+// RUN: %clang -fsyntax-only -MD -MF %t.d -MT foo %s -I %t/sub/dir/..
+// RUN: FileCheck -check-prefix=TEST3 %s < %t.d
+// TEST3: foo:
+// TEST3: sub/dir/..{{/|\\}}empty.h
+
+// Test that system header paths are not expanded with -fno-canonical-system-headers
+// (and also that the -fsystem-system-headers option is accepted)
+//
+// RUN: %clang -fsyntax-only -MD -MF %t.d -MT foo %s -I %t/sub/dir/.. -fcanonical-system-headers -fno-canonical-system-headers
+// RUN: FileCheck -check-prefix=TEST4 %s < %t.d
+// TEST4: foo:
+// TEST4: sub/dir/..{{/|\\}}empty.h
+
+#include <empty.h>

Propchange: cfe/trunk/test/Preprocessor/dependencies-realpath.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the cfe-commits mailing list