Support -M, -MM, and -MMD

Add support for some more options to generate dependency fragments.
-M is likes -MD but doesn't compile anything so the command won't fail
when just supplied a file without all the relevant libs.
-MM and -MMD are like their counterparts but skip system libs.

Note the behavior of -MD has changed to include system libs. Use -MMD
for the old behavior. This matches gcc's corresponding flags
This commit is contained in:
Arthur Williams 2021-06-28 00:27:39 -05:00
parent 64d29c942a
commit ee75521dd5
5 changed files with 36 additions and 3 deletions

View file

@ -1502,8 +1502,11 @@ enum {
TCC_OPTION_w,
TCC_OPTION_pipe,
TCC_OPTION_E,
TCC_OPTION_M,
TCC_OPTION_MD,
TCC_OPTION_MF,
TCC_OPTION_MM,
TCC_OPTION_MMD,
TCC_OPTION_x,
TCC_OPTION_ar,
TCC_OPTION_impdef,
@ -1568,8 +1571,11 @@ static const TCCOption tcc_options[] = {
{ "w", TCC_OPTION_w, 0 },
{ "pipe", TCC_OPTION_pipe, 0},
{ "E", TCC_OPTION_E, 0},
{ "M", TCC_OPTION_M, 0},
{ "MD", TCC_OPTION_MD, 0},
{ "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
{ "MM", TCC_OPTION_MM, 0},
{ "MMD", TCC_OPTION_MMD, 0},
{ "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
{ "ar", TCC_OPTION_ar, 0},
#ifdef TCC_TARGET_PE
@ -1906,8 +1912,20 @@ reparse:
case TCC_OPTION_P:
s->Pflag = atoi(optarg) + 1;
break;
case TCC_OPTION_M:
s->include_sys_deps = 1;
// fall through
case TCC_OPTION_MM:
s->just_deps = 1;
if(!s->deps_outfile)
s->deps_outfile = tcc_strdup("-");
// fall through
case TCC_OPTION_MMD:
s->gen_deps = 1;
break;
case TCC_OPTION_MD:
s->gen_deps = 1;
s->include_sys_deps = 1;
break;
case TCC_OPTION_MF:
s->deps_outfile = tcc_strdup(optarg);

View file

@ -370,9 +370,19 @@ to trigger a stack trace with a message on demand.
Misc options:
@table @option
@item -M
Just output makefile fragment with dependencies
@item -MM
Like -M except mention only user header files, not system header files.
@item -MD
Generate makefile fragment with dependencies.
@item -MMD
Like -MD except mention only user header files, not system header files.
@item -MF depfile
Use @file{depfile} as output for -MD.

7
tcc.c
View file

@ -70,7 +70,10 @@ static const char help[] =
" -nostdinc do not use standard system include paths\n"
" -nostdlib do not link with standard crt and libraries\n"
" -Bdir set tcc's private include/library dir\n"
" -M just output makefile fragment with dependencies\n"
" -MM Like -M but ignore system libs\n"
" -MD generate dependency file for make\n"
" -MMD Like -MMD but ignore system libs\n"
" -MF file specify dependency file name\n"
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
" -m32/64 defer to i386/x86_64 cross compiler\n"
@ -250,7 +253,7 @@ static char *default_outputfile(TCCState *s, const char *first_file)
strcpy(ext, ".exe");
else
#endif
if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext)
if ((s->just_deps || s->output_type == TCC_OUTPUT_OBJ) && !s->option_r && *ext)
strcpy(ext, ".o");
else
strcpy(buf, "a.out");
@ -380,7 +383,7 @@ redo:
} else {
if (!s->outfile)
s->outfile = default_outputfile(s, first_file);
if (tcc_output_file(s, s->outfile))
if (!s->just_deps && tcc_output_file(s, s->outfile))
ret = 1;
else if (s->gen_deps)
gen_makedeps(s, s->outfile, s->deps_outfile);

2
tcc.h
View file

@ -975,7 +975,9 @@ struct TCCState {
char *outfile; /* output filename */
unsigned char option_r; /* option -r */
unsigned char do_bench; /* option -bench */
int just_deps; /* option -M */
int gen_deps; /* option -MD */
int include_sys_deps; /* option -MD */
char *deps_outfile; /* option -MF */
int argc;
char **argv;

View file

@ -1924,7 +1924,7 @@ ST_FUNC void preprocess(int is_bof)
while (i == 1 && (bf = bf->prev))
i = bf->include_next_index;
/* skip system include files */
if (n - i > s1->nb_sysinclude_paths)
if (s1->include_sys_deps || n - i > s1->nb_sysinclude_paths)
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(buf1));
}