From d0cb963994b421dd8a6ff38b8adf50266d44f628 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sun, 25 Oct 2009 20:34:05 +0000 Subject: [PATCH] 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. --- driver/iverilog.man | 22 ++++++++++++++++------ driver/main.c | 46 +++++++++++++++++++++++++++++++++++++++++---- ivlpp/globals.h | 1 + ivlpp/lexor.lex | 27 ++++++++++++++++++++------ ivlpp/main.c | 10 ++++++++-- load_module.cc | 8 ++++++-- main.cc | 4 ++++ 7 files changed, 98 insertions(+), 20 deletions(-) diff --git a/driver/iverilog.man b/driver/iverilog.man index ca2c00951..97a414a8c 100644 --- a/driver/iverilog.man +++ b/driver/iverilog.man @@ -6,7 +6,7 @@ iverilog - Icarus Verilog compiler .B iverilog [\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]] [\-pflag=value] [\-dname] [\-g1995|\-g2001|\-g2005|\-g] -[\-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 diff --git a/driver/main.c b/driver/main.c index a56ca6ef0..d471a0ed0 100644 --- a/driver/main.c +++ b/driver/main.c @@ -39,7 +39,8 @@ const char NOTICE[] = const char HELP[] = "Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]\n" " [-g1995|-g2001|-g2005] [-g]\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 diff --git a/ivlpp/globals.h b/ivlpp/globals.h index 129db8bcc..c30991b06 100644 --- a/ivlpp/globals.h +++ b/ivlpp/globals.h @@ -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(); diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index 2a34f8c74..de39498c6 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -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; diff --git a/ivlpp/main.c b/ivlpp/main.c index 9c360fad9..535b17edf 100644 --- a/ivlpp/main.c +++ b/ivlpp/main.c @@ -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); } diff --git a/load_module.cc b/load_module.cc index e8606e628..646e4ce83 100644 --- a/load_module.cc +++ b/load_module.cc @@ -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; } - diff --git a/main.cc b/main.cc index e0acd91e1..7f3b8ead2 100644 --- a/main.cc +++ b/main.cc @@ -105,6 +105,7 @@ list 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);