Provide different modes for dependency list output.

This patch modifies the iverilog -M command line option to allow
the user to specify an optional output mode that controls which
files get added to the dependency list. This allows the user to
either get a list of all files that contribute to the design,
or a list of the include files, or a list of the module files.
This commit is contained in:
Martin Whitaker 2009-10-25 20:34:05 +00:00 committed by Stephen Williams
parent 1f0857606a
commit d0cb963994
7 changed files with 98 additions and 20 deletions

View File

@ -6,7 +6,7 @@ iverilog - Icarus Verilog compiler
.B iverilog
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]] [\-pflag=value]
[\-dname] [\-g1995|\-g2001|\-g2005|\-g<feature>]
[\-Iincludedir] [\-mmodule] [\-Mfile] [\-Nfile] [\-ooutputfilename]
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
.SH DESCRIPTION
@ -125,11 +125,21 @@ to specify several directories to search, the directories are searched
in the order they appear on the command line.
.TP 8
.B -M\fIpath\fP
Write into the file specified by path a list of files that contribute
to the compilation of the design. This includes files that are
included by include directives and files that are automatically loaded
by library support. The output is one file name per line, with no
leading or trailing space.
This is equivalent to \fB-Mall=path\fP. Preserved for backwards
compatibility.
.TP 8
.B -M\fImode=path\fP
Write into the file specified by path a list of files that contribute to
the compilation of the design. If \fBmode\fP is \fBall\fP or \fBprefix\fP,
this includes files that are included by include directives and files
that are automatically loaded by library support as well as the files
explicitly specified by the user. If \fBmode\fP is \fBinclude\fP, only
files that are included by include directives are listed. If \fBmode\fP
is \fBmodule\fP, only files that are specified by the user or that are
automatically loaded by library support are listed. The output is one
file name per line, with no leading or trailing space. If \fBmode\fP
is \fBprefix\fP, files that are included by include directives are
prefixed by "I " and other files are prefixed by "M ".
.TP 8
.B -m\fImodule\fP
Add this module to the list of VPI modules to be loaded by the

View File

@ -39,7 +39,8 @@ const char NOTICE[] =
const char HELP[] =
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]\n"
" [-g1995|-g2001|-g2005] [-g<feature>]\n"
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
" [-D macro[=defn]] [-I includedir]\n"
" [-M [mode=]depfile] [-m module]\n"
" [-N file] [-o filename] [-p flag=value]\n"
" [-s topmodule] [-t target] [-T min|typ|max]\n"
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
@ -108,6 +109,8 @@ const char*npath = 0;
const char*targ = "vvp";
const char*depfile = 0;
char depmode = 'a';
const char*generation = "2005";
const char*gen_specify = "no-specify";
const char*gen_xtypes = "xtypes";
@ -696,6 +699,37 @@ int process_generation(const char*name)
return 0;
}
int process_depfile(const char*name)
{
const char*cp = strchr(name, '=');
if (cp) {
int match_length = (int)(cp - name) + 1;
if (strncmp(name, "all=", match_length) == 0) {
depmode = 'a';
} else if (strncmp(name, "include=", match_length) == 0) {
depmode = 'i';
} else if (strncmp(name, "module=", match_length) == 0) {
depmode = 'm';
} else if (strncmp(name, "prefix=", match_length) == 0) {
depmode = 'p';
} else {
fprintf(stderr, "Unknown dependency file mode '%.*s'\n\n",
match_length - 1, name);
fprintf(stderr, "Supported modes are:\n");
fprintf(stderr, " all\n");
fprintf(stderr, " include\n");
fprintf(stderr, " module\n");
fprintf(stderr, " prefix\n");
return -1;
}
depfile = cp + 1;
} else {
depmode = 'a';
depfile = name;
}
return 0;
}
/*
* If it exists add the SFT file for the given module.
*/
@ -863,7 +897,8 @@ int main(int argc, char **argv)
break;
case 'M':
depfile = optarg;
if (process_depfile(optarg) != 0)
return -1;
break;
case 'm':
@ -984,7 +1019,10 @@ int main(int argc, char **argv)
fprintf(iconfig_file, "generation:%s\n", gen_system_verilog);
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
fprintf(iconfig_file, "out:%s\n", opath);
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
if (depfile) {
fprintf(iconfig_file, "depfile:%s\n", depfile);
fprintf(iconfig_file, "depmode:%c\n", depmode);
}
while ( (command_filename = get_cmd_file()) ) {
int rc;
@ -1008,7 +1046,7 @@ int main(int argc, char **argv)
destroy_lexor();
if (depfile) {
fprintf(defines_file, "M:%s\n", depfile);
fprintf(defines_file, "M%c:%s\n", depmode, depfile);
}
/* Process parameter definition from command line. The last

View File

@ -42,6 +42,7 @@ extern int line_direct_flag;
extern unsigned error_count;
extern FILE *depend_file;
extern char dep_mode;
/* This is the entry to the lexer. */
extern int yylex();

View File

@ -1520,8 +1520,13 @@ static void do_include()
free(include_dir[0]);
include_dir[0] = 0;
if(depend_file)
fprintf(depend_file, "%s\n", standby->path);
if (depend_file) {
if (dep_mode == 'p') {
fprintf(depend_file, "I %s\n", standby->path);
} else if (dep_mode != 'm') {
fprintf(depend_file, "%s\n", standby->path);
}
}
if (line_direct_flag)
fprintf(yyout, "\n`line 1 \"%s\" 1\n", standby->path);
@ -1648,8 +1653,13 @@ static int load_next_input()
if (line_direct_flag)
fprintf(yyout, "\n`line 1 \"%s\" 0\n", istack->path);
if(depend_file)
fprintf(depend_file, "%s\n", istack->path);
if (depend_file) {
if (dep_mode == 'p') {
fprintf(depend_file, "M %s\n", istack->path);
} else if (dep_mode != 'i') {
fprintf(depend_file, "%s\n", istack->path);
}
}
/* This works around an issue in flex yyrestart() where it
* uses yyin to create a new buffer when one does not exist.
@ -1796,8 +1806,13 @@ void reset_lexor(FILE* out, char* paths[])
exit(1);
}
if(depend_file)
fprintf(depend_file, "%s\n", paths[0]);
if (depend_file) {
if (dep_mode == 'p') {
fprintf(depend_file, "M %s\n", paths[0]);
} else if (dep_mode != 'i') {
fprintf(depend_file, "%s\n", paths[0]);
}
}
yyout = out;

View File

@ -56,6 +56,8 @@ extern const char*optarg;
#endif
/* Path to the dependency file, if there is one. */
char *dep_path = NULL;
/* Dependency file output mode */
char dep_mode = 'a';
/*
@ -146,10 +148,14 @@ static int flist_read_flags(const char*path)
define_macro(optarg, buf, 1, 0);
free(buf);
} else if (strcmp(cp,"M") == 0) {
} else if ((strcmp(cp,"Ma") == 0)
|| (strcmp(cp,"Mi") == 0)
|| (strcmp(cp,"Mm") == 0)
|| (strcmp(cp,"Mp") == 0)) {
if (dep_path) {
fprintf(stderr, "duplicate -M flag.\n");
} else {
} else {
dep_mode = cp[1];
dep_path = strdup(arg);
}

View File

@ -46,6 +46,7 @@ static struct module_library*library_list = 0;
static struct module_library*library_last = 0;
const char dir_character = '/';
extern char depfile_mode;
extern FILE *depend_file;
/*
@ -72,7 +73,11 @@ bool load_module(const char*type)
sprintf(path, "%s%c%s", lcur->dir, dir_character, (*cur).second);
if(depend_file) {
fprintf(depend_file, "%s\n", path);
if (depfile_mode == 'p') {
fprintf(depend_file, "M %s\n", path);
} else if (depfile_mode != 'i') {
fprintf(depend_file, "%s\n", path);
}
fflush(depend_file);
}
@ -190,4 +195,3 @@ int build_library_index(const char*path, bool key_case_sensitive)
return 0;
}

View File

@ -105,6 +105,7 @@ list<perm_string> roots;
char*ivlpp_string = 0;
char depfile_mode = 'a';
char* depfile_name = NULL;
FILE *depend_file = NULL;
@ -427,6 +428,9 @@ static void read_iconfig_file(const char*ipath)
} else {
}
} else if (strcmp(buf, "depmode") == 0) {
depfile_mode = *cp;
} else if (strcmp(buf, "depfile") == 0) {
depfile_name = strdup(cp);