DependencyFile.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. //===--- DependencyFile.cpp - Generate dependency file --------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This code generates dependency files.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/Frontend/Utils.h"
  13. #include "clang/Basic/FileManager.h"
  14. #include "clang/Basic/SourceManager.h"
  15. #include "clang/Frontend/DependencyOutputOptions.h"
  16. #include "clang/Frontend/FrontendDiagnostic.h"
  17. #include "clang/Lex/DirectoryLookup.h"
  18. #include "clang/Lex/ModuleMap.h"
  19. #include "clang/Lex/PPCallbacks.h"
  20. #include "clang/Lex/Preprocessor.h"
  21. #include "clang/Serialization/ASTReader.h"
  22. #include "llvm/ADT/StringSet.h"
  23. #include "llvm/Support/FileSystem.h"
  24. #include "llvm/Support/Path.h"
  25. #include "llvm/Support/raw_ostream.h"
  26. #include <optional>
  27. using namespace clang;
  28. namespace {
  29. struct DepCollectorPPCallbacks : public PPCallbacks {
  30. DependencyCollector &DepCollector;
  31. Preprocessor &PP;
  32. DepCollectorPPCallbacks(DependencyCollector &L, Preprocessor &PP)
  33. : DepCollector(L), PP(PP) {}
  34. void LexedFileChanged(FileID FID, LexedFileChangeReason Reason,
  35. SrcMgr::CharacteristicKind FileType, FileID PrevFID,
  36. SourceLocation Loc) override {
  37. if (Reason != PPCallbacks::LexedFileChangeReason::EnterFile)
  38. return;
  39. // Dependency generation really does want to go all the way to the
  40. // file entry for a source location to find out what is depended on.
  41. // We do not want #line markers to affect dependency generation!
  42. if (std::optional<StringRef> Filename =
  43. PP.getSourceManager().getNonBuiltinFilenameForID(FID))
  44. DepCollector.maybeAddDependency(
  45. llvm::sys::path::remove_leading_dotslash(*Filename),
  46. /*FromModule*/ false, isSystem(FileType), /*IsModuleFile*/ false,
  47. /*IsMissing*/ false);
  48. }
  49. void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
  50. SrcMgr::CharacteristicKind FileType) override {
  51. StringRef Filename =
  52. llvm::sys::path::remove_leading_dotslash(SkippedFile.getName());
  53. DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
  54. /*IsSystem=*/isSystem(FileType),
  55. /*IsModuleFile=*/false,
  56. /*IsMissing=*/false);
  57. }
  58. void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
  59. StringRef FileName, bool IsAngled,
  60. CharSourceRange FilenameRange,
  61. OptionalFileEntryRef File, StringRef SearchPath,
  62. StringRef RelativePath, const Module *Imported,
  63. SrcMgr::CharacteristicKind FileType) override {
  64. if (!File)
  65. DepCollector.maybeAddDependency(FileName, /*FromModule*/false,
  66. /*IsSystem*/false, /*IsModuleFile*/false,
  67. /*IsMissing*/true);
  68. // Files that actually exist are handled by FileChanged.
  69. }
  70. void HasInclude(SourceLocation Loc, StringRef SpelledFilename, bool IsAngled,
  71. OptionalFileEntryRef File,
  72. SrcMgr::CharacteristicKind FileType) override {
  73. if (!File)
  74. return;
  75. StringRef Filename =
  76. llvm::sys::path::remove_leading_dotslash(File->getName());
  77. DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
  78. /*IsSystem=*/isSystem(FileType),
  79. /*IsModuleFile=*/false,
  80. /*IsMissing=*/false);
  81. }
  82. void EndOfMainFile() override {
  83. DepCollector.finishedMainFile(PP.getDiagnostics());
  84. }
  85. };
  86. struct DepCollectorMMCallbacks : public ModuleMapCallbacks {
  87. DependencyCollector &DepCollector;
  88. DepCollectorMMCallbacks(DependencyCollector &DC) : DepCollector(DC) {}
  89. void moduleMapFileRead(SourceLocation Loc, const FileEntry &Entry,
  90. bool IsSystem) override {
  91. StringRef Filename = Entry.getName();
  92. DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
  93. /*IsSystem*/IsSystem,
  94. /*IsModuleFile*/false,
  95. /*IsMissing*/false);
  96. }
  97. };
  98. struct DepCollectorASTListener : public ASTReaderListener {
  99. DependencyCollector &DepCollector;
  100. FileManager &FileMgr;
  101. DepCollectorASTListener(DependencyCollector &L, FileManager &FileMgr)
  102. : DepCollector(L), FileMgr(FileMgr) {}
  103. bool needsInputFileVisitation() override { return true; }
  104. bool needsSystemInputFileVisitation() override {
  105. return DepCollector.needSystemDependencies();
  106. }
  107. void visitModuleFile(StringRef Filename,
  108. serialization::ModuleKind Kind) override {
  109. DepCollector.maybeAddDependency(Filename, /*FromModule*/true,
  110. /*IsSystem*/false, /*IsModuleFile*/true,
  111. /*IsMissing*/false);
  112. }
  113. bool visitInputFile(StringRef Filename, bool IsSystem,
  114. bool IsOverridden, bool IsExplicitModule) override {
  115. if (IsOverridden || IsExplicitModule)
  116. return true;
  117. // Run this through the FileManager in order to respect 'use-external-name'
  118. // in case we have a VFS overlay.
  119. if (auto FE = FileMgr.getOptionalFileRef(Filename))
  120. Filename = FE->getName();
  121. DepCollector.maybeAddDependency(Filename, /*FromModule*/true, IsSystem,
  122. /*IsModuleFile*/false, /*IsMissing*/false);
  123. return true;
  124. }
  125. };
  126. } // end anonymous namespace
  127. void DependencyCollector::maybeAddDependency(StringRef Filename,
  128. bool FromModule, bool IsSystem,
  129. bool IsModuleFile,
  130. bool IsMissing) {
  131. if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
  132. addDependency(Filename);
  133. }
  134. bool DependencyCollector::addDependency(StringRef Filename) {
  135. StringRef SearchPath;
  136. #ifdef _WIN32
  137. // Make the search insensitive to case and separators.
  138. llvm::SmallString<256> TmpPath = Filename;
  139. llvm::sys::path::native(TmpPath);
  140. std::transform(TmpPath.begin(), TmpPath.end(), TmpPath.begin(), ::tolower);
  141. SearchPath = TmpPath.str();
  142. #else
  143. SearchPath = Filename;
  144. #endif
  145. if (Seen.insert(SearchPath).second) {
  146. Dependencies.push_back(std::string(Filename));
  147. return true;
  148. }
  149. return false;
  150. }
  151. static bool isSpecialFilename(StringRef Filename) {
  152. return Filename == "<built-in>";
  153. }
  154. bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule,
  155. bool IsSystem, bool IsModuleFile,
  156. bool IsMissing) {
  157. return !isSpecialFilename(Filename) &&
  158. (needSystemDependencies() || !IsSystem);
  159. }
  160. DependencyCollector::~DependencyCollector() { }
  161. void DependencyCollector::attachToPreprocessor(Preprocessor &PP) {
  162. PP.addPPCallbacks(std::make_unique<DepCollectorPPCallbacks>(*this, PP));
  163. PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
  164. std::make_unique<DepCollectorMMCallbacks>(*this));
  165. }
  166. void DependencyCollector::attachToASTReader(ASTReader &R) {
  167. R.addListener(
  168. std::make_unique<DepCollectorASTListener>(*this, R.getFileManager()));
  169. }
  170. DependencyFileGenerator::DependencyFileGenerator(
  171. const DependencyOutputOptions &Opts)
  172. : OutputFile(Opts.OutputFile), Targets(Opts.Targets),
  173. IncludeSystemHeaders(Opts.IncludeSystemHeaders),
  174. PhonyTarget(Opts.UsePhonyTargets),
  175. AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), SeenMissingHeader(false),
  176. IncludeModuleFiles(Opts.IncludeModuleFiles),
  177. OutputFormat(Opts.OutputFormat), InputFileIndex(0) {
  178. for (const auto &ExtraDep : Opts.ExtraDeps) {
  179. if (addDependency(ExtraDep.first))
  180. ++InputFileIndex;
  181. }
  182. }
  183. void DependencyFileGenerator::attachToPreprocessor(Preprocessor &PP) {
  184. // Disable the "file not found" diagnostic if the -MG option was given.
  185. if (AddMissingHeaderDeps)
  186. PP.SetSuppressIncludeNotFoundError(true);
  187. DependencyCollector::attachToPreprocessor(PP);
  188. }
  189. bool DependencyFileGenerator::sawDependency(StringRef Filename, bool FromModule,
  190. bool IsSystem, bool IsModuleFile,
  191. bool IsMissing) {
  192. if (IsMissing) {
  193. // Handle the case of missing file from an inclusion directive.
  194. if (AddMissingHeaderDeps)
  195. return true;
  196. SeenMissingHeader = true;
  197. return false;
  198. }
  199. if (IsModuleFile && !IncludeModuleFiles)
  200. return false;
  201. if (isSpecialFilename(Filename))
  202. return false;
  203. if (IncludeSystemHeaders)
  204. return true;
  205. return !IsSystem;
  206. }
  207. void DependencyFileGenerator::finishedMainFile(DiagnosticsEngine &Diags) {
  208. outputDependencyFile(Diags);
  209. }
  210. /// Print the filename, with escaping or quoting that accommodates the three
  211. /// most likely tools that use dependency files: GNU Make, BSD Make, and
  212. /// NMake/Jom.
  213. ///
  214. /// BSD Make is the simplest case: It does no escaping at all. This means
  215. /// characters that are normally delimiters, i.e. space and # (the comment
  216. /// character) simply aren't supported in filenames.
  217. ///
  218. /// GNU Make does allow space and # in filenames, but to avoid being treated
  219. /// as a delimiter or comment, these must be escaped with a backslash. Because
  220. /// backslash is itself the escape character, if a backslash appears in a
  221. /// filename, it should be escaped as well. (As a special case, $ is escaped
  222. /// as $$, which is the normal Make way to handle the $ character.)
  223. /// For compatibility with BSD Make and historical practice, if GNU Make
  224. /// un-escapes characters in a filename but doesn't find a match, it will
  225. /// retry with the unmodified original string.
  226. ///
  227. /// GCC tries to accommodate both Make formats by escaping any space or #
  228. /// characters in the original filename, but not escaping backslashes. The
  229. /// apparent intent is so that filenames with backslashes will be handled
  230. /// correctly by BSD Make, and by GNU Make in its fallback mode of using the
  231. /// unmodified original string; filenames with # or space characters aren't
  232. /// supported by BSD Make at all, but will be handled correctly by GNU Make
  233. /// due to the escaping.
  234. ///
  235. /// A corner case that GCC gets only partly right is when the original filename
  236. /// has a backslash immediately followed by space or #. GNU Make would expect
  237. /// this backslash to be escaped; however GCC escapes the original backslash
  238. /// only when followed by space, not #. It will therefore take a dependency
  239. /// from a directive such as
  240. /// #include "a\ b\#c.h"
  241. /// and emit it as
  242. /// a\\\ b\\#c.h
  243. /// which GNU Make will interpret as
  244. /// a\ b\
  245. /// followed by a comment. Failing to find this file, it will fall back to the
  246. /// original string, which probably doesn't exist either; in any case it won't
  247. /// find
  248. /// a\ b\#c.h
  249. /// which is the actual filename specified by the include directive.
  250. ///
  251. /// Clang does what GCC does, rather than what GNU Make expects.
  252. ///
  253. /// NMake/Jom has a different set of scary characters, but wraps filespecs in
  254. /// double-quotes to avoid misinterpreting them; see
  255. /// https://msdn.microsoft.com/en-us/library/dd9y37ha.aspx for NMake info,
  256. /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
  257. /// for Windows file-naming info.
  258. static void PrintFilename(raw_ostream &OS, StringRef Filename,
  259. DependencyOutputFormat OutputFormat) {
  260. // Convert filename to platform native path
  261. llvm::SmallString<256> NativePath;
  262. llvm::sys::path::native(Filename.str(), NativePath);
  263. if (OutputFormat == DependencyOutputFormat::NMake) {
  264. // Add quotes if needed. These are the characters listed as "special" to
  265. // NMake, that are legal in a Windows filespec, and that could cause
  266. // misinterpretation of the dependency string.
  267. if (NativePath.find_first_of(" #${}^!") != StringRef::npos)
  268. OS << '\"' << NativePath << '\"';
  269. else
  270. OS << NativePath;
  271. return;
  272. }
  273. assert(OutputFormat == DependencyOutputFormat::Make);
  274. for (unsigned i = 0, e = NativePath.size(); i != e; ++i) {
  275. if (NativePath[i] == '#') // Handle '#' the broken gcc way.
  276. OS << '\\';
  277. else if (NativePath[i] == ' ') { // Handle space correctly.
  278. OS << '\\';
  279. unsigned j = i;
  280. while (j > 0 && NativePath[--j] == '\\')
  281. OS << '\\';
  282. } else if (NativePath[i] == '$') // $ is escaped by $$.
  283. OS << '$';
  284. OS << NativePath[i];
  285. }
  286. }
  287. void DependencyFileGenerator::outputDependencyFile(DiagnosticsEngine &Diags) {
  288. if (SeenMissingHeader) {
  289. llvm::sys::fs::remove(OutputFile);
  290. return;
  291. }
  292. std::error_code EC;
  293. llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::OF_TextWithCRLF);
  294. if (EC) {
  295. Diags.Report(diag::err_fe_error_opening) << OutputFile << EC.message();
  296. return;
  297. }
  298. outputDependencyFile(OS);
  299. }
  300. void DependencyFileGenerator::outputDependencyFile(llvm::raw_ostream &OS) {
  301. // Write out the dependency targets, trying to avoid overly long
  302. // lines when possible. We try our best to emit exactly the same
  303. // dependency file as GCC>=10, assuming the included files are the
  304. // same.
  305. const unsigned MaxColumns = 75;
  306. unsigned Columns = 0;
  307. for (StringRef Target : Targets) {
  308. unsigned N = Target.size();
  309. if (Columns == 0) {
  310. Columns += N;
  311. } else if (Columns + N + 2 > MaxColumns) {
  312. Columns = N + 2;
  313. OS << " \\\n ";
  314. } else {
  315. Columns += N + 1;
  316. OS << ' ';
  317. }
  318. // Targets already quoted as needed.
  319. OS << Target;
  320. }
  321. OS << ':';
  322. Columns += 1;
  323. // Now add each dependency in the order it was seen, but avoiding
  324. // duplicates.
  325. ArrayRef<std::string> Files = getDependencies();
  326. for (StringRef File : Files) {
  327. if (File == "<stdin>")
  328. continue;
  329. // Start a new line if this would exceed the column limit. Make
  330. // sure to leave space for a trailing " \" in case we need to
  331. // break the line on the next iteration.
  332. unsigned N = File.size();
  333. if (Columns + (N + 1) + 2 > MaxColumns) {
  334. OS << " \\\n ";
  335. Columns = 2;
  336. }
  337. OS << ' ';
  338. PrintFilename(OS, File, OutputFormat);
  339. Columns += N + 1;
  340. }
  341. OS << '\n';
  342. // Create phony targets if requested.
  343. if (PhonyTarget && !Files.empty()) {
  344. unsigned Index = 0;
  345. for (auto I = Files.begin(), E = Files.end(); I != E; ++I) {
  346. if (Index++ == InputFileIndex)
  347. continue;
  348. PrintFilename(OS, *I, OutputFormat);
  349. OS << ":\n";
  350. }
  351. }
  352. }