diff --git a/main.c b/main.c index f744a7d..690b0d3 100644 --- a/main.c +++ b/main.c @@ -12,6 +12,7 @@ static StringArray opt_include; static bool opt_E; static bool opt_M; static bool opt_MD; +static bool opt_MMD; static bool opt_MP; static bool opt_S; static bool opt_c; @@ -22,6 +23,7 @@ static char *opt_MT; static char *opt_o; static StringArray ld_extra_args; +static StringArray std_include_paths; char *base_file; static char *output_file; @@ -52,6 +54,10 @@ static void add_default_include_paths(char *argv0) { strarray_push(&include_paths, "/usr/local/include"); strarray_push(&include_paths, "/usr/include/x86_64-linux-gnu"); strarray_push(&include_paths, "/usr/include"); + + // Keep a copy of the standard include paths for -MMD option. + for (int i = 0; i < include_paths.len; i++) + strarray_push(&std_include_paths, include_paths.data[i]); } static void define(char *str) { @@ -245,6 +251,11 @@ static void parse_args(int argc, char **argv) { continue; } + if (!strcmp(argv[i], "-MMD")) { + opt_MD = opt_MMD = true; + continue; + } + if (!strcmp(argv[i], "-cc1-input")) { base_file = argv[++i]; continue; @@ -395,6 +406,16 @@ static void print_tokens(Token *tok) { fprintf(out, "\n"); } +static bool in_std_include_path(char *path) { + for (int i = 0; i < std_include_paths.len; i++) { + char *dir = std_include_paths.data[i]; + int len = strlen(dir); + if (strncmp(dir, path, len) == 0 && path[len] == '/') + return true; + } + return false; +} + // If -M options is given, the compiler write a list of input files to // stdout in a format that "make" command can read. This feature is // used to automate file dependency management. @@ -417,13 +438,21 @@ static void print_dependencies(void) { File **files = get_input_files(); - for (int i = 0; files[i]; i++) + for (int i = 0; files[i]; i++) { + if (opt_MMD && in_std_include_path(files[i]->name)) + continue; fprintf(out, " \\\n %s", files[i]->name); + } + fprintf(out, "\n\n"); - if (opt_MP) - for (int i = 1; files[i]; i++) + if (opt_MP) { + for (int i = 1; files[i]; i++) { + if (opt_MMD && in_std_include_path(files[i]->name)) + continue; fprintf(out, "%s:\n\n", quote_makefile(files[i]->name)); + } + } } static Token *must_tokenize_file(char *path) {