The -V flag gets version information from all parts.

When the -V flag is passed to the iverilog command, we can easily
print the version information for the driver itself, but it is also
valuable to probe all the components that would have been used for
a real compile. So the driver executes the preprocessor and the ivl
core to have them print version information.

The ivl core program also tries to load the target code generator
and get version information to print. For this to work, create a new
optional entry point "target_query" that takes a query key string as
an argument and returns a const string as the result. Use this with
the key "version" to get version information out of the target.
This commit is contained in:
Stephen Williams 2008-09-07 21:54:46 -07:00
parent 4898cd04c6
commit 527f5c4849
14 changed files with 273 additions and 108 deletions

View File

@ -18,6 +18,23 @@
#
SHELL = /bin/sh
# Normally, the "make" will build all the files only by dependencies.
# The MODE, however, can control your rebuild intentions. The proper way
# to use the MODE is on the make command like, this this:
#
# make MODE=XXXX all
#
# The possible MODE= values are:
#
# regular
# Build as normal
#
# full
# Do some extra builds. in particular:
# Build version.h again, even if it already exists.
#
MODE=regular
# This version string is only used in the version message printed
# by the compiler. It reflects the assigned version number for the
# product as a whole. Most components also print the CVS Name: token
@ -52,15 +69,15 @@ MAN = @MAN@
PS2PDF = @PS2PDF@
GIT = @GIT@
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@
CXXFLAGS = -Wall @CXXFLAGS@
PICFLAGS = @PICFLAG@
LDFLAGS = @rdynamic@ @LDFLAGS@
all: dep version.h ivl@EXEEXT@
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) VERSION=$(VERSION) $@); done
for dir in ivlpp ; \
do (cd $$dir ; $(MAKE) $@); done
do (cd $$dir ; $(MAKE) VERSION=$(VERSION) $@); done
cd driver ; $(MAKE) VERSION=$(VERSION) $@
# In the windows world, the installer will need a dosify program to
@ -186,7 +203,9 @@ iverilog-vpi.pdf: iverilog-vpi.ps
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
# version.h file in the source tree (included in snapshots and releases), and
# finally use nothing.
ifeq ($(MODE),full)
.PHONY: version.h
endif
# "true" and "false" in the next few lines are Unix shell command names
ifeq ($(GIT),none)
GIT_PRESENT = false

View File

@ -51,6 +51,7 @@ const char HELP[] =
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
@ -259,18 +260,102 @@ static const char*my_tempfile(const char*str, FILE**fout)
return pathbuf;
}
static int t_version_only(void)
{
remove(source_path);
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civlpp -V", pbase, sep);
system(tmp);
fflush(0);
snprintf(tmp, sizeof tmp, "%s%civl -V -C%s -C%s", pbase, sep,
iconfig_path, iconfig_common_path);
system(tmp);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
remove(defines_path);
remove(compiled_defines_path);
}
return 0;
}
static void build_preprocess_command(int e_flag)
{
snprintf(tmp, sizeof tmp, "%s%civlpp %s%s -F%s -f%s -p%s ",
pbase,sep, verbose_flag?" -v":"",
e_flag?"":" -L", defines_path, source_path,
compiled_defines_path);
}
static int t_preprocess_only(void)
{
int rc;
char*cmd;
unsigned ncmd;
build_preprocess_command(1);
ncmd = strlen(tmp);
cmd = malloc(ncmd+1);
strcpy(cmd, tmp);
if (strcmp(opath,"-") != 0) {
snprintf(tmp, sizeof tmp, " > %s", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
}
if (verbose_flag)
printf("preprocess: %s\n", cmd);
rc = system(cmd);
remove(source_path);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
remove(defines_path);
remove(compiled_defines_path);
}
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
return WEXITSTATUS(rc);
}
fprintf(stderr, "Command signaled: %s\n", cmd);
free(cmd);
return -1;
}
return 0;
}
/*
* This is the default target type. It looks up the bits that are
* needed to run the command from the configuration file (which is
* already parsed for us) so we can handle must of the generic cases.
*/
static int t_default(char*cmd, unsigned ncmd)
static int t_compile()
{
unsigned rc;
/* Start by building the preprocess command line. */
build_preprocess_command(0);
size_t ncmd = strlen(tmp);
char*cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
#ifdef __MINGW32__
unsigned ncmd_start = ncmd;
#endif
/* Build the ivl command and pipe it to the preprocessor. */
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
rc = strlen(tmp);
cmd = realloc(cmd, ncmd+rc+1);
@ -533,8 +618,6 @@ void add_sft_file(const char *module)
int main(int argc, char **argv)
{
char*cmd;
unsigned ncmd;
int e_flag = 0;
int version_flag = 0;
int opt, idx, rc;
@ -748,9 +831,6 @@ int main(int argc, char **argv)
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
printf("Copyright 1998-2008 Stephen Williams\n");
puts(NOTICE);
if (version_flag)
return 0;
}
/* Make a common conf file path to reflect the target. */
@ -833,61 +913,11 @@ int main(int argc, char **argv)
fclose(defines_file);
defines_file = 0;
if (source_count == 0) {
if (source_count == 0 && !version_flag) {
fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP);
return 1;
}
/* Start building the preprocess command line. */
sprintf(tmp, "%s%civlpp %s%s -F%s -f%s -p%s ", pbase,sep,
verbose_flag?" -v":"",
e_flag?"":" -L", defines_path, source_path,
compiled_defines_path);
ncmd = strlen(tmp);
cmd = malloc(ncmd + 1);
strcpy(cmd, tmp);
/* If the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
user wants it. */
if (e_flag) {
int rc;
if (strcmp(opath,"-") != 0) {
sprintf(tmp, " > %s", opath);
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
strcpy(cmd+ncmd, tmp);
ncmd += strlen(tmp);
}
if (verbose_flag)
printf("preprocess: %s\n", cmd);
rc = system(cmd);
remove(source_path);
fclose(iconfig_file);
if ( ! getenv("IVERILOG_ICONFIG")) {
remove(iconfig_path);
remove(defines_path);
remove(compiled_defines_path);
}
if (rc != 0) {
if (WIFEXITED(rc)) {
fprintf(stderr, "errors preprocessing Verilog program.\n");
return WEXITSTATUS(rc);
}
fprintf(stderr, "Command signaled: %s\n", cmd);
free(cmd);
return -1;
}
return 0;
}
fprintf(iconfig_file, "iwidth:%u\n", integer_width);
/* Write the preprocessor command needed to preprocess a
@ -899,5 +929,16 @@ int main(int argc, char **argv)
/* Done writing to the iconfig file. Close it now. */
fclose(iconfig_file);
return t_default(cmd, ncmd);
/* If we're only here for th verion output, then we're done. */
if (version_flag)
return t_version_only();
/* If the -E flag was given on the command line, then all we
do is run the preprocessor and put the output where the
user wants it. */
if (e_flag)
return t_preprocess_only();
/* Otherwise, this is a full compile. */
return t_compile();
}

View File

@ -1927,7 +1927,7 @@ extern unsigned ivl_switch_lineno(ivl_switch_t net);
#endif
extern DLLEXPORT int target_design(ivl_design_t des);
extern DLLEXPORT const char* target_query(const char*key);
/* target_design
@ -1945,6 +1945,7 @@ extern DLLEXPORT int target_design(ivl_design_t des);
ivl core. This function is how the target module is invoked. */
typedef int (*target_design_f)(ivl_design_t des);
typedef const char* (*target_query_f) (const char*key);
_END_DECL

View File

@ -40,7 +40,7 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@

View File

@ -17,7 +17,8 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include "config.h"
# include "version.h"
const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n"
@ -35,8 +36,6 @@ const char NOTICE[] =
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
;
const char VERSION[] = "$Name: $ $State: Exp $";
# include <stdio.h>
# include <stdlib.h>
#ifdef HAVE_MALLOC_H
@ -229,7 +228,7 @@ int main(int argc, char*argv[])
include_dir[0] = 0; /* 0 is reserved for the current files path. */
include_dir[1] = strdup(".");
while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:v")) != EOF) switch (opt) {
while ((opt=getopt(argc, argv, "F:f:K:Lo:p:P:vV")) != EOF) switch (opt) {
case 'F':
flist_read_flags(optarg);
@ -284,12 +283,19 @@ int main(int argc, char*argv[])
}
case 'v':
fprintf(stderr, "Icarus Verilog Preprocessor version %s\n",
VERSION);
fprintf(stderr, "Icarus Verilog Preprocessor version "
VERSION " (" VERSION_TAG ")\n\n");
fprintf(stderr, "%s\n", COPYRIGHT);
fputs(NOTICE, stderr);
break;
case 'V':
fprintf(stdout, "Icarus Verilog Preprocessor version "
VERSION " (" VERSION_TAG ")\n\n");
fprintf(stdout, "%s\n", COPYRIGHT);
fputs(NOTICE, stdout);
return 0;
default:
flag_errors += 1;
break;
@ -304,7 +310,8 @@ int main(int argc, char*argv[])
" -o<fil> - Send the output to <fil>\n"
" -p<fil> - Write precompiled defines to <fil>\n"
" -P<fil> - Read precompiled defines from <fil>\n"
" -v - Print version information\n",
" -v - Verbose\n"
" -V - Print version information and quit\n",
argv[0]);
return flag_errors;
}

24
main.cc
View File

@ -20,6 +20,7 @@ const char COPYRIGHT[] =
*/
# include "config.h"
# include "version.h"
const char NOTICE[] =
" This program is free software; you can redistribute it and/or modify\n"
@ -76,8 +77,6 @@ extern "C" const char*optarg;
/* Count errors detected in flag processing. */
unsigned flag_errors = 0;
const char VERSION[] = "$Name: $";
const char*basedir = ".";
/*
@ -532,6 +531,7 @@ int main(int argc, char*argv[])
{
bool help_flag = false;
bool times_flag = false;
bool version_flag = false;
const char* net_path = 0;
const char* pf_path = 0;
@ -575,10 +575,8 @@ int main(int argc, char*argv[])
# endif
break;
case 'V':
cout << "Icarus Verilog version " << VERSION << endl;
cout << COPYRIGHT << endl;
cout << endl << NOTICE << endl;
return 0;
version_flag = true;
break;
default:
flag_errors += 1;
break;
@ -587,8 +585,20 @@ int main(int argc, char*argv[])
if (flag_errors)
return flag_errors;
if (version_flag) {
cout << "\n\nIcarus Verilog Parser/Elaborator version "
<< VERSION << " (" << VERSION_TAG << ")" << endl;
cout << COPYRIGHT << endl;
cout << endl << NOTICE << endl;
dll_target_obj.test_version(flags["DLL"]);
return 0;
}
if (help_flag) {
cout << "Icarus Verilog version " << VERSION << endl <<
cout << "Icarus Verilog Parser/Elaborator version "
<< VERSION << " (" << VERSION_TAG << ")" << endl <<
"usage: ivl <options> <file>\n"
"options:\n"
"\t-C <name> Config file from driver.\n"

View File

@ -2578,3 +2578,39 @@ bool dll_target::signal_paths(const NetNet*net)
return true;
}
void dll_target::test_version(const char*target_name)
{
dll_ = ivl_dlopen(target_name);
if ((dll_ == 0) && (target_name[0] != '/')) {
size_t len = strlen(basedir) + 1 + strlen(target_name) + 1;
char*tmp = new char[len];
sprintf(tmp, "%s/%s", basedir, target_name);
dll_ = ivl_dlopen(tmp);
delete[]tmp;
}
if (dll_ == 0) {
cout << "\n\nUnable to load " << target_name
<< " for version details." << endl;
return;
}
target_query_f target_query = (target_query_f)ivl_dlsym(dll_, LU "target_query" TU);
if (target_query == 0) {
cerr << "Target " << target_name
<< " has no version hooks." << endl;
return;
}
const char*version_string = (*target_query) ("version");
if (version_string == 0) {
cerr << "Target " << target_name
<< " has no version string" << endl;
return;
}
cout << target_name << ": " << version_string << endl;
}

View File

@ -63,6 +63,10 @@ struct ivl_design_s {
*/
struct dll_target : public target_t, public expr_scan_t {
// This is a special function for loading and testing the
// version of a loadable target code generator.
void test_version(const char*target_name);
bool start_design(const Design*);
int end_design(const Design*);

View File

@ -35,7 +35,7 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I.. -I$(srcdir)/.. -I$(srcdir) @CPPFLAGS@ @DEFS@ @PICFLAG@
CPPFLAGS = @ident_support@ -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@

View File

@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: null.c,v 1.7 2002/08/12 01:35:03 steve Exp $"
#endif
# include "config.h"
@ -28,35 +25,34 @@
# include "ivl_target.h"
static const char*version_string =
"Icarus Verilog NULL Code Generator " VERSION "\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 2 of the License, or\n"
" (at your option) any later version.\n"
"\n"
" This program is distributed in the hope that it will be useful,\n"
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License\n"
" along with this program; if not, write to the Free Software\n"
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
;
int target_design(ivl_design_t des)
{
return 0;
}
/*
* $Log: null.c,v $
* Revision 1.7 2002/08/12 01:35:03 steve
* conditional ident string using autoconfig.
*
* Revision 1.6 2001/09/30 16:45:10 steve
* Fix some Cygwin DLL handling. (Venkat Iyer)
*
* Revision 1.5 2001/07/25 03:10:50 steve
* Create a config.h.in file to hold all the config
* junk, and support gcc 3.0. (Stephan Boettcher)
*
* Revision 1.4 2001/05/22 02:14:47 steve
* Update the mingw build to not require cygwin files.
*
* Revision 1.3 2001/05/20 15:09:40 steve
* Mingw32 support (Venkat Iyer)
*
* Revision 1.2 2001/02/07 22:21:59 steve
* ivl_target header search path fixes.
*
* Revision 1.1 2000/12/02 04:50:32 steve
* Make the null target into a loadable target.
*
*/
const char* target_query(const char*key)
{
if (strcmp(key,"version") == 0)
return version_string;
return 0;
}

View File

@ -35,7 +35,7 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I.. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CPPFLAGS = @ident_support@ -I.. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@

View File

@ -28,8 +28,26 @@
# include "priv.h"
# include <stdlib.h>
# include <inttypes.h>
# include <string.h>
# include <assert.h>
static const char*version_string =
"Icarus Verilog Stub Target " VERSION "\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 2 of the License, or\n"
" (at your option) any later version.\n"
"\n"
" This program is distributed in the hope that it will be useful,\n"
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License\n"
" along with this program; if not, write to the Free Software\n"
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
;
FILE*out;
int stub_errors = 0;
@ -1608,3 +1626,11 @@ int target_design(ivl_design_t des)
return stub_errors;
}
const char* target_query(const char*key)
{
if (strcmp(key,"version") == 0)
return version_string;
return 0;
}

View File

@ -38,7 +38,7 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ @PICFLAG@
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@ @PICFLAG@
CFLAGS = -Wall @CFLAGS@
LDFLAGS = @LDFLAGS@

View File

@ -26,6 +26,23 @@
# include <sys/types.h>
# include <sys/stat.h>
static const char*version_string =
"Icarus Verilog VVP Code Generator " VERSION "\n"
" This program is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" the Free Software Foundation; either version 2 of the License, or\n"
" (at your option) any later version.\n"
"\n"
" This program is distributed in the hope that it will be useful,\n"
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
" GNU General Public License for more details.\n"
"\n"
" You should have received a copy of the GNU General Public License\n"
" along with this program; if not, write to the Free Software\n"
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
;
FILE*vvp_out = 0;
int vvp_errors = 0;
@ -119,3 +136,11 @@ int target_design(ivl_design_t des)
return rc + vvp_errors;
}
const char* target_query(const char*key)
{
if (strcmp(key,"version") == 0)
return version_string;
return 0;
}