diff --git a/src/frontend/cxx/cli.cc b/src/frontend/cxx/cli.cc index a2f9aa81..795cd681 100644 --- a/src/frontend/cxx/cli.cc +++ b/src/frontend/cxx/cli.cc @@ -132,6 +132,12 @@ std::vector options{ {"-dM", "Print macro definitions in -E mode instead of normal output", &CLI::opt_dM}, + {"-M", "Print dependencies of the main source file", + &CLI::opt_M}, + + {"-MM", "Print dependencies of the main source file, excluding system path", + &CLI::opt_MM}, + {"-S", "Only run preprocess and compilation steps", &CLI::opt_S, CLIOptionVisibility::kExperimental}, diff --git a/src/frontend/cxx/cli.h b/src/frontend/cxx/cli.h index 6c7d61e5..9c7ec57e 100644 --- a/src/frontend/cxx/cli.h +++ b/src/frontend/cxx/cli.h @@ -54,6 +54,8 @@ class CLI { bool opt_ast_dump = false; bool opt_ir_dump = false; bool opt_dM = false; + bool opt_MM = false; + bool opt_M = false; bool opt_dump_symbols = false; bool opt_dump_tokens = false; bool opt_E = false; diff --git a/src/frontend/cxx/frontend.cc b/src/frontend/cxx/frontend.cc index 21970508..d51809b3 100644 --- a/src/frontend/cxx/frontend.cc +++ b/src/frontend/cxx/frontend.cc @@ -238,7 +238,7 @@ auto runOnFile(const CLI& cli, const std::string& fileName) -> bool { } if (auto source = readAll(fileName)) { - if (cli.opt_E && !cli.opt_dM) { + if (cli.opt_E && !(cli.opt_dM || cli.opt_M || cli.opt_MM)) { preprocesor->preprocess(std::move(*source), fileName, output); shouldExit = true; } else { @@ -247,6 +247,12 @@ auto runOnFile(const CLI& cli, const std::string& fileName) -> bool { if (cli.opt_dM) { preprocesor->printMacros(output); shouldExit = true; + } else if (cli.opt_M) { + preprocesor->printDependencies(output, false); + shouldExit = true; + } else if (cli.opt_MM) { + preprocesor->printDependencies(output, true); + shouldExit = true; } else if (cli.opt_dump_tokens) { dumpTokens(cli, unit, output); shouldExit = true; diff --git a/src/parser/cxx/preprocessor.cc b/src/parser/cxx/preprocessor.cc index 7fc45d0f..296a37ee 100644 --- a/src/parser/cxx/preprocessor.cc +++ b/src/parser/cxx/preprocessor.cc @@ -2262,6 +2262,27 @@ void Preprocessor::printMacros(std::ostream &out) const { } } +void Preprocessor::printDependencies(std::ostream &out, bool noSysPath) const { + if (d->sourceFiles_.size() == 0) return; + const auto p = fs::path(d->sourceFiles_[0]->fileName); + const std::string stem = p.stem(); + out << cxx::format("{}.o:", stem); + for (const auto &sourceFile : d->sourceFiles_) { + if (noSysPath) { + bool isSysPath = false; + for (const auto &sysPath : d->systemIncludePaths_) { + if (sourceFile->fileName.find(sysPath) == 0) { + isSysPath = true; + break; + } + } + if (isSysPath) continue; + } + out << cxx::format(" \\\n {}", sourceFile->fileName); + } + out << "\n"; +} + void Preprocessor::getTokenStartPosition(const Token &token, unsigned *line, unsigned *column, std::string_view *fileName) const { diff --git a/src/parser/cxx/preprocessor.h b/src/parser/cxx/preprocessor.h index 5585be5f..89938a00 100644 --- a/src/parser/cxx/preprocessor.h +++ b/src/parser/cxx/preprocessor.h @@ -97,6 +97,8 @@ class Preprocessor { void printMacros(std::ostream &out) const; + void printDependencies(std::ostream &out, bool noSysPath) const; + void getTokenStartPosition(const Token &token, unsigned *line, unsigned *column, std::string_view *fileName) const;