diff --git a/driver/cflexor.lex b/driver/cflexor.lex index 4d2ab39a0..532d3abb8 100644 --- a/driver/cflexor.lex +++ b/driver/cflexor.lex @@ -90,6 +90,8 @@ int cmdfile_stack_ptr = 0; "+vhdl-work+" { BEGIN(PLUS_ARGS); return TOK_VHDL_WORK; } +"+vhdl-libdir+" { BEGIN(PLUS_ARGS); return TOK_VHDL_LIBDIR; } + /* If it is not any known plus-flag, return the generic form. */ "+"[^\n \t\b\f\r+]* { cflval.text = strdup(yytext); diff --git a/driver/cfparse.y b/driver/cfparse.y index 36044d0a0..db2759e61 100644 --- a/driver/cfparse.y +++ b/driver/cfparse.y @@ -59,7 +59,7 @@ static void translate_file_name(char*text) %token TOK_Da TOK_Dc TOK_Dv TOK_Dy %token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE -%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE TOK_VHDL_WORK +%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE TOK_VHDL_WORK TOK_VHDL_LIBDIR %token TOK_PLUSARG TOK_PLUSWORD TOK_STRING %% @@ -163,6 +163,14 @@ item free($2); } + | TOK_VHDL_LIBDIR TOK_PLUSARG + { char*tmp = substitutions($2); + vhdlpp_libdir = realloc(vhdlpp_libdir, (vhdlpp_libdir_cnt+1)*sizeof(char*)); + vhdlpp_libdir[vhdlpp_libdir_cnt] = tmp; + vhdlpp_libdir_cnt += 1; + free($2); + } + /* The +incdir token introduces a list of + arguments that are the include directories to search. */ diff --git a/driver/globals.h b/driver/globals.h index 36968fc1e..55cc00da8 100644 --- a/driver/globals.h +++ b/driver/globals.h @@ -25,6 +25,8 @@ extern unsigned integer_width; extern const char*vhdlpp_work; +extern const char**vhdlpp_libdir; +extern unsigned vhdlpp_libdir_cnt; /* Perform variable substitutions on the string. */ extern char* substitutions(const char*str); diff --git a/driver/main.c b/driver/main.c index 5b0d25ecd..73c0d666e 100644 --- a/driver/main.c +++ b/driver/main.c @@ -115,6 +115,9 @@ const char*npath = 0; const char*targ = "vvp"; const char*depfile = 0; +const char**vhdlpp_libdir = 0; +unsigned vhdlpp_libdir_cnt = 0; + char depmode = 'a'; const char*generation = "2005"; @@ -1105,6 +1108,8 @@ int main(int argc, char **argv) vhdlpp_work = "ivl_vhdl_work"; fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep); fprintf(defines_file, "vhdlpp-work:%s\n", vhdlpp_work); + for (idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1) + fprintf(defines_file, "vhdlpp-libdir:%s\n", vhdlpp_libdir[idx]); /* Process parameter definition from command line. The last defined would override previous ones. */ diff --git a/ivlpp/globals.h b/ivlpp/globals.h index 3d1455b22..2c7e89600 100644 --- a/ivlpp/globals.h +++ b/ivlpp/globals.h @@ -38,6 +38,9 @@ extern char*vhdlpp_path; /* vhdlpp work directory */ extern char*vhdlpp_work; +extern char**vhdlpp_libdir; +extern unsigned vhdlpp_libdir_cnt; + extern int relative_include; /* This flag is true if #line directives are to be generated. */ @@ -48,6 +51,8 @@ extern unsigned error_count; extern FILE *depend_file; extern char dep_mode; +extern int verbose_flag; + /* This is the entry to the lexer. */ extern int yylex(); diff --git a/ivlpp/lexor.lex b/ivlpp/lexor.lex index 09ec6aa48..2e054ee90 100644 --- a/ivlpp/lexor.lex +++ b/ivlpp/lexor.lex @@ -1764,6 +1764,7 @@ static void open_input_file(struct include_stack_t*isp) { char*cp; int is_vhdl = 0; + unsigned idx; isp->file = 0; @@ -1787,14 +1788,29 @@ static void open_input_file(struct include_stack_t*isp) size_t cmdlen = strlen(vhdlpp_path); cmdlen += strlen(isp->path); - cmdlen += 32; + cmdlen += 8+strlen(vhdlpp_work); + + size_t liblen = 1; + char*libs = strdup(""); + for (idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1) { + size_t next_len = 6 + strlen(vhdlpp_libdir[idx]); + libs = realloc(libs, liblen+next_len); + snprintf(libs+liblen-1, next_len, " -L'%s'", vhdlpp_libdir[idx]); + liblen = strlen(libs) + 1; + } + + cmdlen += liblen; char*cmd = malloc(cmdlen); - snprintf(cmd, cmdlen, "%s -w'%s' %s", vhdlpp_path, vhdlpp_work, isp->path); + snprintf(cmd, cmdlen, "%s -w'%s'%s %s", vhdlpp_path, vhdlpp_work, libs, isp->path); + + if (verbose_flag) + fprintf(stderr, "Invoke vhdlpp: %s\n", cmd); isp->file = popen(cmd, "r"); isp->file_close = pclose; + free(libs); free(cmd); return; } diff --git a/ivlpp/main.c b/ivlpp/main.c index a467e6a7a..f0e6cb871 100644 --- a/ivlpp/main.c +++ b/ivlpp/main.c @@ -57,11 +57,15 @@ extern const char*optarg; char *dep_path = NULL; /* Dependency file output mode */ char dep_mode = 'a'; +/* verbose flag */ +int verbose_flag = 0; /* Path to vhdlpp */ char *vhdlpp_path = 0; /* vhdlpp work directory */ char *vhdlpp_work = 0; +char**vhdlpp_libdir = 0; +unsigned vhdlpp_libdir_cnt = 0; /* * Keep in source_list an array of pointers to file names. The array * is terminated by a pointer to null. @@ -183,6 +187,12 @@ static int flist_read_flags(const char*path) vhdlpp_work = strdup(arg); } + } else if (strcmp(cp,"vhdlpp-libdir") == 0) { + vhdlpp_libdir = realloc(vhdlpp_libdir, + (vhdlpp_libdir_cnt+1)*sizeof(char*)); + vhdlpp_libdir[vhdlpp_libdir_cnt] = strdup(arg); + vhdlpp_libdir_cnt += 1; + } else { fprintf(stderr, "%s: Invalid keyword %s\n", path, cp); } @@ -331,6 +341,7 @@ int main(int argc, char*argv[]) VERSION " (" VERSION_TAG ")\n\n"); fprintf(stderr, "%s\n\n", COPYRIGHT); fputs(NOTICE, stderr); + verbose_flag = 1; break; case 'V':