Allow -mingw and -ivl flags to stand alone.
This commit is contained in:
parent
d91733d32c
commit
c692f1708c
|
|
@ -1,38 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Gus Baldauf (gus@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* iverilog-vpi.c
|
||||
*
|
||||
* this program is provides the functionality
|
||||
* of iverilog-vpi.sh under Win32
|
||||
* this program provides the functionality of iverilog-vpi.sh under Win32
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Macros used for compiling and linking */
|
||||
|
||||
#define IVERILOG_VPI_CC "gcc"
|
||||
#define IVERILOG_VPI_CXX "gcc"
|
||||
#define IVERILOG_VPI_CC "gcc" /* no .exe extension */
|
||||
#define IVERILOG_VPI_CXX "gcc" /* no .exe extension */
|
||||
#define IVERILOG_VPI_CFLAGS "-O" /* -I appended later */
|
||||
#define IVERILOG_VPI_LD "gcc"
|
||||
#define IVERILOG_VPI_LD "gcc" /* no .exe extension */
|
||||
#define IVERILOG_VPI_LDFLAGS "-shared -Wl,--enable-auto-image-base"
|
||||
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi" /* -L prepended later */
|
||||
|
||||
/* pointers to global strings */
|
||||
|
||||
static struct global_strings {
|
||||
char *pCCSRC; // list of C source files
|
||||
char *pCXSRC; // list of C++ source files
|
||||
char *pOBJ; // list of object files
|
||||
char *pLIB; // list of library files
|
||||
char *pOUT; // output file name (.vpi extension)
|
||||
char *pMINGW; // path to MinGW directory
|
||||
char *pIVL; // path to IVL directory
|
||||
char *pCFLAGS; // CFLAGS option
|
||||
char *pLDLIBS; // LDLIBS option
|
||||
char *pNewPath; // new PATH environment variable setting
|
||||
char *pCCSRC; /* list of C source files */
|
||||
char *pCXSRC; /* list of C++ source files */
|
||||
char *pOBJ; /* list of object files */
|
||||
char *pLIB; /* list of library files */
|
||||
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
||||
char *pMINGW; /* path to MinGW directory */
|
||||
char *pIVL; /* path to IVL directory */
|
||||
char *pCFLAGS; /* CFLAGS option */
|
||||
char *pLDLIBS; /* LDLIBS option */
|
||||
char *pNewPath; /* new PATH environment variable setting */
|
||||
} gstr;
|
||||
|
||||
|
||||
|
|
@ -61,9 +82,11 @@ static void myExit(int exitVal)
|
|||
|
||||
/* display usage summary and exit */
|
||||
|
||||
static void usage(char *name)
|
||||
static void usage()
|
||||
{
|
||||
fprintf(stderr,"usage: %s [--name=name] [-llibrary] [-mingw=dir] [-ivl=dir] sourcefile...\n",name);
|
||||
fprintf(stderr,"usage: iverilog-vpi [--name=name] [-llibrary] [-mingw=dir] [-ivl=dir] sourcefile...\n");
|
||||
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
|
||||
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
|
||||
myExit(1);
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +227,7 @@ static int GetRegistryKey(char *key, char **value)
|
|||
fprintf(stderr,"error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
regKeyBuffer[regKeySize] = 0; // makes sure there is a trailing NULL
|
||||
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
|
||||
|
||||
lrv = RegQueryValueEx(hkKey,key,NULL,®KeyType,regKeyBuffer,®KeySize);
|
||||
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
|
||||
|
|
@ -241,13 +264,16 @@ static void SetRegistryKey(char *key, char *value)
|
|||
|
||||
RegSetValueEx(hkKey,key,0,REG_SZ,value,strlen(value)+1);
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
printf("info: storing %s in Windows' registry entry\n",value);
|
||||
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n",key);
|
||||
}
|
||||
|
||||
/* parse the command line, assign results to global variable strings */
|
||||
|
||||
static int parse(int argc, char *argv[])
|
||||
{
|
||||
int idx;
|
||||
int idx, srcFileCnt=0;
|
||||
|
||||
char dot_c_ext[] = ".c";
|
||||
char dot_cc_ext[] = ".cc";
|
||||
|
|
@ -262,18 +288,21 @@ static int parse(int argc, char *argv[])
|
|||
|
||||
for (idx=1; idx<argc; ++idx) {
|
||||
if (endsIn(dot_c_ext,argv[idx])) { /* check for C source files */
|
||||
++srcFileCnt;
|
||||
append(&gstr.pCCSRC,argv[idx]);
|
||||
append(&gstr.pCCSRC," ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_c_ext));
|
||||
}
|
||||
else if (endsIn(dot_cc_ext,argv[idx])) { /* check for C++ source files */
|
||||
++srcFileCnt;
|
||||
append(&gstr.pCXSRC,argv[idx]);
|
||||
append(&gstr.pCXSRC," ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cc_ext));
|
||||
}
|
||||
else if (endsIn(dot_o_ext,argv[idx])) { /* check for compiled object files */
|
||||
++srcFileCnt;
|
||||
append(&gstr.pOBJ,argv[idx]);
|
||||
append(&gstr.pOBJ," ");
|
||||
if (!*gstr.pOUT)
|
||||
|
|
@ -294,61 +323,123 @@ static int parse(int argc, char *argv[])
|
|||
return 0; /* different from iverilog-vpi.sh, we don't ignore accept arguments */
|
||||
}
|
||||
|
||||
if (!*gstr.pOUT)
|
||||
usage(argv[0]);
|
||||
if (0 == srcFileCnt)
|
||||
assign(&gstr.pOUT,""); /* in case they used --name with no source files */
|
||||
|
||||
append(&gstr.pOUT,".vpi"); /* the result file should have a .vpi extension */
|
||||
append(&gstr.pOUT," ");
|
||||
if (!*gstr.pOUT) { /* normally it's an error if there are no *.c,*.cc,*.o files */
|
||||
if (!*gstr.pMINGW && !*gstr.pIVL) /* unless they are just setting the IVL or MinGW registry entries */
|
||||
usage();
|
||||
}
|
||||
else {
|
||||
append(&gstr.pOUT,".vpi"); /* the result file should have a .vpi extension */
|
||||
append(&gstr.pOUT," ");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* see if we can find iverilog and mingw */
|
||||
/* do minimal check that the MinGW root directory looks valid */
|
||||
|
||||
static void checkMingwDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path;
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
||||
if (irv) {
|
||||
fprintf(stderr,"error: %s does not appear to be the valid root directory\n",root);
|
||||
fprintf(stderr," of MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
|
||||
fprintf(stderr," point to the MinGW root directory. For a Windows command\n");
|
||||
fprintf(stderr," shell the option would be something like -mingw=c:\\mingw\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
}
|
||||
|
||||
/* do minimal check that the Icarus Verilog root directory looks valid */
|
||||
|
||||
static void checkIvlDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path;
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pIVL);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\vvp.exe");
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
||||
if (irv) {
|
||||
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
|
||||
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi.exe to\n");
|
||||
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
|
||||
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
}
|
||||
}
|
||||
|
||||
/* see if we can find mingw root */
|
||||
|
||||
#define IVL_REGKEY_MINGW "MingwDir"
|
||||
|
||||
static void setup_mingw_environment()
|
||||
{
|
||||
char *pOldPATH;
|
||||
char *pOldPATH = getenv("PATH"); /* get current path */
|
||||
|
||||
char *RegKeyMinGW;
|
||||
initDynString(&RegKeyMinGW);
|
||||
|
||||
if (*gstr.pMINGW)
|
||||
if (*gstr.pMINGW) {
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
|
||||
}
|
||||
else
|
||||
if (!GetRegistryKey(IVL_REGKEY_MINGW,&RegKeyMinGW)) {
|
||||
fprintf(stderr,"error: can not locate MinGW directory, use the -mingw option\n");
|
||||
deInitDynString(RegKeyMinGW);
|
||||
if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
|
||||
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
|
||||
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
||||
fprintf(stderr," a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\mingw For a Cygwin shell the option would be\n");
|
||||
fprintf(stderr," something like -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
|
||||
pOldPATH = getenv("PATH"); /* get current path */
|
||||
|
||||
assign(&gstr.pNewPath,"PATH="); /* create new path */
|
||||
append(&gstr.pNewPath,*gstr.pMINGW ? gstr.pMINGW : RegKeyMinGW);
|
||||
append(&gstr.pNewPath,gstr.pMINGW);
|
||||
appendBackSlash(&gstr.pNewPath);
|
||||
append(&gstr.pNewPath,"bin;");
|
||||
append(&gstr.pNewPath,pOldPATH);
|
||||
|
||||
_putenv(gstr.pNewPath); /* place new path in environment variable */
|
||||
|
||||
deInitDynString(RegKeyMinGW);
|
||||
}
|
||||
|
||||
/* see if we can find iverilog root */
|
||||
|
||||
#define IVL_REGKEY_IVL "InstallDir"
|
||||
|
||||
static void setup_ivl_environment()
|
||||
{
|
||||
char *RegKeyIVL;
|
||||
initDynString(&RegKeyIVL);
|
||||
|
||||
if (*gstr.pIVL)
|
||||
if (*gstr.pIVL) {
|
||||
checkIvlDir(gstr.pIVL);
|
||||
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
|
||||
}
|
||||
else
|
||||
if (!GetRegistryKey(IVL_REGKEY_IVL,&RegKeyIVL)) {
|
||||
fprintf(stderr,"error: can not locate Icarus Verilog directory, use the -ivl option\n");
|
||||
deInitDynString(RegKeyIVL);
|
||||
if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
|
||||
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
|
||||
fprintf(stderr," of iverilog-vpi.exe to point to the Icarus Verilog root directory.\n");
|
||||
fprintf(stderr," For a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
|
||||
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
}
|
||||
|
||||
|
|
@ -356,19 +447,17 @@ static void setup_ivl_environment()
|
|||
|
||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
|
||||
append(&gstr.pCFLAGS," -I");
|
||||
append(&gstr.pCFLAGS,*gstr.pIVL ? gstr.pIVL : RegKeyIVL);
|
||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCFLAGS);
|
||||
append(&gstr.pCFLAGS,"include");
|
||||
|
||||
/* build up the LDFLAGS option string */
|
||||
|
||||
assign(&gstr.pLDLIBS,"-L");
|
||||
append(&gstr.pLDLIBS,*gstr.pIVL ? gstr.pIVL : RegKeyIVL);
|
||||
append(&gstr.pLDLIBS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pLDLIBS);
|
||||
append(&gstr.pLDLIBS,"lib ");
|
||||
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
|
||||
|
||||
deInitDynString(RegKeyIVL);
|
||||
}
|
||||
|
||||
/* compile source modules */
|
||||
|
|
@ -418,6 +507,14 @@ static void compile_and_link()
|
|||
char *buf=0;
|
||||
int iRet, compile_errors = 0;
|
||||
|
||||
/* print out the mingw and ivl directories to help the user debug problems */
|
||||
|
||||
printf("info: %s will be used as the MinGW root directory.\n",gstr.pMINGW);
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
|
||||
printf("info: %s will be used as the Icarus Verilog root directory.\n",gstr.pIVL);
|
||||
checkIvlDir(gstr.pIVL);
|
||||
|
||||
/* compile */
|
||||
|
||||
compile(gstr.pCCSRC,&gstr.pOBJ,".c" ,&compile_errors,IVERILOG_VPI_CC ); /* compile the C source files */
|
||||
|
|
@ -456,12 +553,13 @@ int main(int argc, char *argv[])
|
|||
init();
|
||||
|
||||
if (!parse(argc,argv))
|
||||
usage(argv[0]);
|
||||
usage();
|
||||
|
||||
setup_mingw_environment();
|
||||
setup_ivl_environment();
|
||||
|
||||
compile_and_link();
|
||||
if (*gstr.pOUT) /* are there any *.c,*.cc,*.o files specified */
|
||||
compile_and_link();
|
||||
|
||||
myExit(0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue