home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
vide
/
mmakerbc.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-23
|
18KB
|
678 lines
//===============================================================
// mmaker.cpp - makefileMaker Class for VIDE
//
// Copyright (C) 1995,1996, 1997, 1998 Bruce E. Wampler
//
// This file is part of the V C++ GUI Framework, and is covered
// under the terms of the GNU Library General Public License,
// Version 2. This library has NO WARRANTY. See the source file
// vapp.cxx for more complete information about license terms.
//===============================================================
#include <v/vnotice.h>
#include <v/vos.h>
#include "mmaker.h"
#include "videapp.h"
//==================>>> makefileMaker::fieldLen <<<============================
const int makefileMaker::fieldLen = 256;
static const char SecProjOpts[] = "//% Section 1 - PROJECT OPTIONS";
static const char SecProjOptsEnd[] = "//%end-proj-opts";
static const char SecMakefile[] = "//% Section 2 - MAKEFILE";
static const char SecOptions[] = "//% Section 3 - OPTIONS";
static const char SecOptionsEnd[] = "//%end-options";
static const char SecHomeV[] = "//% Section 4 - HOMEV";
static const char SecTarget[] = "//% Section 5 - TARGET FILE";
static const char SecObjFiles[] = "//% Section 6 - SOURCE FILES";
static const char SecObjFilesEnd[] = "//%end-srcfiles";
static const char SecCompiler[] = "//% Section 7 - COMPILER NAME";
static const char SecIncDirs[] = "//% Section 8 - INCLUDE DIRECTORIES";
static const char SecIncDirsEnd[] = "//%end-include-dirs";
static const char SecLibDirs[] = "//% Section 9 - LIBRARY DIRECTORIES";
static const char SecLibDirsEnd[] = "//%end-library-dirs";
static const char SecDefs[] = "//% Section 10 - DEFINITIONS";
static const char SecDefsPoolEnd[] = "//%end-defs-pool";
static const char SecDefsEnd[] = "//%end-defs";
static const char SecCFlags[] = "//% Section 11 - C FLAGS";
static const char SecLibFlags[] = "//% Section 12 - LIBRARY FLAGS";
static const char SecSrcDir[] = "//% Section 13 - SRC DIRECTORY";
static const char SecObjDir[] = "//% Section 14 - OBJ DIRECTORY";
static const char SecBinDir[] = "//% Section 15 - BIN DIRECTORY";
static const char SecUserTargets[] = "//% Section 16 - USER TARGETS";
static const char SecUserTargetsEnd[] = "//%end-user-targets";
//==================>>> makefileMaker::makefileMaker <<<=========================
makefileMaker::makefileMaker()
{
makeName = new char[fieldLen];
homeV = new char[fieldLen];
exeName = new char[fieldLen];
cc = new char[fieldLen];
cFlags = new char[fieldLen];
Libs = new char[fieldLen];
ObjDir = new char[fieldLen];
BinDir = new char[fieldLen];
SrcDir = new char[fieldLen];
setDefaults();
cmdw = ((videApp*)theApp)->GetMsgWindow();
}
//======================>>> makefileMaker::~makefileMaker <<<============================
makefileMaker::~makefileMaker()
{
delete [] makeName;
delete [] homeV;
delete [] exeName;
delete [] cc;
delete [] cFlags;
delete [] Libs;
delete [] BinDir;
delete [] SrcDir;
delete [] ObjDir;
}
//======================>>> makefileMaker::srcN2ObjN <<<=========================
char* makefileMaker::srcN2ObjN(char* n)
{
static char objn[fieldLen];
strcpy(objn, n);
int len = strlen(objn);
int ix;
// replace .cpp with .o
for (ix = len - 1 ; ix >= 0 ; --ix)
if (objn[ix] == '.')
break;
objn[ix] = 0;
strcat(objn,".o");
return stripDir(objn);
}
//======================>>> makefileMaker::eraseAll <<============================
void makefileMaker::eraseAll()
{
projOpts.erase();
incDirs.erase();
libDirs.erase();
objFiles.erase();
defsPool.erase();
curDefs.erase();
curOpts.erase();
rules.erase();
userTargets.erase();
strcpy(makeName,"");
strcpy(homeV,"");
strcpy(exeName,"");
strcpy(cc,"");
strcpy(cFlags,"");
strcpy(Libs, "");
strcpy(ObjDir,"");
strcpy(BinDir,"");
strcpy(SrcDir,"");
}
//======================>>> makefileMaker::setDefaults <<============================
void makefileMaker::setDefaults()
{
//erase previous definitions
eraseAll();
// init each one
strcpy(makeName,"Makefile.v");
vOS vos;
if (vos.vGetEnvVal("HOMEV",homeV,fieldLen) < 1)
strcpy(homeV,"C:/v");
strcpy(exeName,"foo.exe");
strcpy(cc,"g++");
strcpy(cFlags,"-O");
strcpy(Libs, "-lV -lcomctl32 -mwindows");
strcpy(ObjDir,".");
strcpy(BinDir,".");
strcpy(SrcDir,".");
libDirs.insert(-1,"$(HOMEV)/lib");
incDirs.insert(-1,"$(HOMEV)/include");
}
//======================>>> makefileMaker::stripDir <<<============================
char * makefileMaker::stripDir(char* n)
{
for (int ix = strlen(n) - 1 ; ix >= 0 ; --ix)
{
if (n[ix] == '/' || n[ix] == '\\')
{
return &n[ix+1];
}
}
return n;
}
//======================>>> makefileMaker::addFile <<<============================
BOOL makefileMaker::addFile(char *n)
{
//adds a new source file to the list
if (!*n)
return false;
// Filter name here... (add a behavior switch eventually)
char* addName = stripDir(n); // strip leading dir part
for (int ix = 0 ; objFiles.list[ix] != 0 ; ++ix)
if (strcmp(objFiles.list[ix], addName) == 0)
return false; //don't add a obj file twice
objFiles.insert(-1,addName);
return true;
}
//======================>>> makefileMaker::findRule <<<============================
void makefileMaker::findRule(char* name)
{
//finds the rules to build object file pointed by name
vOS vos; // To execute g++
char command[500]; // command line
char hvbuff[256];
cmdw = ((videApp*)theApp)->GetMsgWindow();
strcpy(command,"g++");
for (int ix = 0 ; incDirs.list[ix] != 0 ; ++ix)
{
char *incdir = incDirs.list[ix];
char *hvp = strstr(incdir,"$(HOMEV)/");
if (hvp != 0)
{
// Have $(HOMEV) in the path, so we must replace the
// $(HOMEV) with the real homeV path.
strcpy(hvbuff,homeV);
strcat(hvbuff, hvp+strlen("$(HOMEV)") );
incdir = hvbuff;
}
strcat(command," -I");
strcat(command,incdir);
if (strlen(command) > 480)
break;
}
strcat(command," -MM "); strcat(command, name);
static char makedep[] = "makedep.vtm";
static char makeerr[] = "makeerr.vtm";
char currlin[256];
if (vos.vRunProcess(command, makedep, makeerr, 1, 1) != 0)
{
CANTMAKE:
cmdw->AddLine(command);
vos.vDeleteFile(makedep);
ifstream em(makeerr);
if (em)
{
while(em.getline(currlin,256,'\n'))
cmdw->AddLine(currlin);
em.close();
}
vos.vDeleteFile(makeerr);
return;
}
ifstream deps(makedep);
if (!deps)
goto CANTMAKE;
while ( deps.getline(currlin, 256, '\n'))
{
rules.insert(-1,currlin);
}
deps.close();
vos.vDeleteFile(makedep);
vos.vDeleteFile(makeerr);
}
//======================>>> makefileMaker::saveMakefile <<<============================
void makefileMaker::saveMakefile()
{
//builds the file named makefile using infos stored in project
cmdw = ((videApp*)theApp)->GetMsgWindow();
ofstream mkf(makeName); // where to write makefile
//header
char buff[120];
char date[20];
vGetLocalTime(buff);
vGetLocalDate(date);
cmdw->AddLine("Building Makefile -- Running g++ to generate dependencies...");
mkf << "#=======================================================================\n";
mkf << "#@V@:Note: File generated by VIDE makefile maker ";
mkf << "(" << buff << " " << date << ").\n";
mkf << "#=======================================================================\n\n";
mkf << "# Standard and User define options:\n";
// Options
int nxtOpts = curOpts.size();
int ix;
for (ix = 0 ; ix < nxtOpts ; ++ix)
{
mkf << curOpts.list[ix] << endl;
}
mkf << endl;
//Compiler
mkf << "CC \t=\t" << cc << "\n\n";
// HomeV
mkf << "HOMEV\t=\t" << homeV << endl;
//Dirs
mkf << "VPATH\t=\t$(HOMEV)/include" << endl;
mkf << "oDir\t=\t" << ObjDir << endl; //Obj Dir
mkf << "Bin\t=\t" << BinDir << endl; //Bin Dir
mkf << "Src\t=\t" << SrcDir << endl; //Src Dir
mkf << "libDirs\t=";
int nxtld = libDirs.size();
for ( ix = 0 ; ix < nxtld ; ++ix)
{
mkf << "\t-L" << libDirs.list[ix];
if (ix + 1 < nxtld)
mkf << " \\";
mkf << endl;
}
mkf << endl;
mkf << "incDirs\t=";
int nxtid = incDirs.size();
for ( ix = 0 ; ix < nxtid ; ++ix)
{
mkf << "\t-I" << incDirs.list[ix];
if (ix + 1 < nxtid)
mkf << " \\";
mkf << endl;
}
mkf << endl;
//Libs
mkf << "LIBS\t=\t" << Libs << endl;
//C_FLAGS & paths to includes
mkf << "C_FLAGS\t=\t" << cFlags;
//defines
int nxtcd = curDefs.size();
for ( ix = 0 ; ix < nxtcd ; ++ix)
{
mkf << "\\\n\t" << curDefs.list[ix];
}
mkf << endl << endl;
//sources
int nxtof = objFiles.size();
mkf << "SRCS\t=";
for ( ix = 0 ; ix < nxtof ; ++ix)
{
mkf << "\\\n\t$(Src)/" << objFiles.list[ix];
}
mkf << endl << endl;
//objects
mkf << "EXOBJS\t=";
for ( ix = 0 ; ix < nxtof ; ++ix)
{
char *objn = srcN2ObjN(objFiles.list[ix]);
mkf << "\\\n\t$(oDir)/" << objn;
}
mkf << endl << endl;
mkf << "#@# Targets follow ---------------------------------"
<< endl << endl;
//target file
//all:
mkf << "all: $(Bin)/" << exeName << endl << endl;
//objs:
mkf << "objs: $(EXOBJS)\n\n";
//cleanobjs:
mkf << "cleanobjs:\n\trm -f $(EXOBJS)" << endl << endl;
// cleanbin
mkf << "cleanbin:\n\trm -f $(Bin)/" << exeName << endl << endl;
// clean
mkf << "clean:\t cleanobjs" << endl << endl;
// cleanall
mkf << "cleanall:\t cleanobjs cleanbin" << endl << endl;
mkf << "#@# User Targets follow ---------------------------------"
<< endl << endl;
for ( ix = 0 ; userTargets.list[ix] != 0 ; ++ix)
mkf << userTargets.list[ix] << endl;
mkf << endl;
mkf << "#@# Dependency rules follow -----------------------------"
<< endl << endl;
//dependency rules
mkf << "$(Bin)/" << exeName
<< ": $(EXOBJS)" << endl << "\t$(CC) -o $(Bin)/"
<< exeName << " $(EXOBJS) $(incDirs) $(libDirs) $(LIBS)" << endl ;
for ( ix = 0 ; objFiles.list[ix] != 0 ; ix++)
findRule(objFiles.list[ix]);
int lim = rules.size();
for ( ix = 0 ; ix < lim ; ++ix)
{
mkf << endl << "$(oDir)/" << rules.list[ix] << endl;
// check for continuation lines
while (*(rules.list[ix]+strlen(rules.list[ix])-1) == '\\')
{
++ix;
if (rules.list[ix])
mkf << rules.list[ix] << endl;
}
mkf << "\t$(CC) $(C_FLAGS) $(incDirs) -c -o $@ $<" << endl;
}
mkf.close();
strcpy(buff,makeName); strcat(buff," - Makefile saved.");
cmdw->AddLine(buff);
}
//======================>>> makefileMaker::saveProject <<<============================
void makefileMaker::saveProject (char *nameIn)
{
char n[300];
if (strlen(nameIn) > 296)
strcpy(n,"BADFILE.tmp");
else
strcpy(n,nameIn);
int len = strlen(n);
int ix;
for (ix = len - 1 ; ix >= 0 ; --ix)
{
if (n[ix] == '.' || n[ix] == '/' || n[ix] == '\\')
break;
}
if (n[ix] != '.') // user didn't supply extension
strcat(n,".vpj");
ofstream prjf(n);
//header
char buff[40];
char date[20];
vGetLocalTime(buff);
vGetLocalDate(date);
prjf << "//=======================================================================\n";
prjf << "//@V@:Note: Project File generated by VIDE: ";
prjf << "(" << buff << " " << date << ").\n";
prjf << "//CAUTION! Hand edit only if you know what you are doing!\n";
prjf << "//=======================================================================\n\n";
// Project Options
prjf << SecProjOpts << endl;
for (int nxtOpts = 0 ; projOpts.list[nxtOpts] != 0 ; ++nxtOpts)
prjf << projOpts.list[nxtOpts] << endl;
prjf << SecProjOptsEnd << endl << endl;
// Makefile name
prjf << SecMakefile << endl;
prjf << makeName << endl << endl;
// Options
prjf << SecOptions << endl;
for ( nxtOpts = 0 ; curOpts.list[nxtOpts] != 0 ; ++nxtOpts)
prjf << curOpts.list[nxtOpts] << endl;
prjf << SecOptionsEnd << endl << endl;
// HOMEV
prjf << SecHomeV << endl;
prjf << homeV << endl << endl;
// 1) name of exe target file
prjf << SecTarget << endl;
prjf << exeName << endl << endl;
// 2) object files
prjf << SecObjFiles << endl;
for ( ix = 0 ; objFiles.list[ix] != 0 ; ++ix)
{
prjf << objFiles.list[ix] << endl;
}
prjf << SecObjFilesEnd << endl << endl;
// 3) compiler name
prjf << SecCompiler << endl;
prjf << cc << endl << endl;
// 4) include dirs
prjf << SecIncDirs << endl;
for (int nxtid = 0 ; incDirs.list[nxtid] != 0 ; ++nxtid)
prjf << incDirs.list[nxtid] << endl;
prjf << SecIncDirsEnd << endl << endl;
// 5) lib dirs
prjf << SecLibDirs << endl;
for (int ld = 0 ; libDirs.list[ld] != 0 ; ++ld)
prjf << libDirs.list[ld] << endl;
prjf << SecLibDirsEnd << endl << endl;
// 6) defs
prjf << SecDefs << endl;
for ( ix = 0 ; defsPool.list[ix] != 0 ; ++ix)
prjf << defsPool.list[ix] << endl;
prjf << SecDefsPoolEnd << endl;
for ( ix = 0 ; curDefs.list[ix] != 0 ; ++ix)
prjf << curDefs.list[ix] << endl;
prjf << SecDefsEnd << endl << endl;
// 7) cflag
prjf << SecCFlags << endl;
prjf << cFlags << endl << endl;
// 8) libflag
prjf << SecLibFlags << endl;
prjf << Libs << endl << endl;
// src directory
prjf << SecSrcDir << endl;
prjf << SrcDir << endl << endl;
// 9) object directory
prjf << SecObjDir << endl;
prjf << ObjDir << endl << endl;
//10) bin directory
prjf << SecBinDir << endl;
prjf << BinDir << endl << endl;
// User Targets
prjf << endl << "//% User targets section. Following lines will be" << endl;
prjf << "//% inserted into Makefile right before the generated cleanall target." << endl;
prjf << "//% The Project File editor does not edit these lines - edit the .vpj" << endl;
prjf << "//% directly. You should know what you are doing." << endl;
prjf << SecUserTargets << endl;
for ( ld = 0 ; userTargets.list[ld] != 0 ; ++ld)
prjf << userTargets.list[ld] << endl;
prjf << SecUserTargetsEnd << endl << endl;
prjf.close();
}
//===================>>> makefileMaker::getSectionEntry <<<===========================
BOOL makefileMaker::getSectionEntry(ifstream &prjf, const char* head, char* value)
{
// read section head into value
char skipStr[256];
if (!prjf)
return false;
for (prjf.getline(skipStr, 256, '\n') ; // skip line
prjf && strcmp(skipStr,head) != 0 ;
prjf.getline(skipStr, 256, '\n'))
;
for (prjf.getline(skipStr, 256, '\n') ; // skip blank lines
prjf && (*skipStr == 0 || *skipStr == ' ') ;
prjf.getline(skipStr, 256, '\n'))
;
strcpy(value,skipStr); // copy to output
if (!prjf)
return false;
else
return true;
}
//===================>>> makefileMaker::getSectionList <<<============================
BOOL makefileMaker::getSectionList(ifstream &prjf, const char* head, const char* term, vSList& sl)
{
char skipStr[256];
if (!prjf)
return false;
if (head && *head) // allow no head - assumes at right location
{
for (prjf.getline(skipStr, 256, '\n') ; // skip line
prjf && strcmp(skipStr,head) != 0 ;
prjf.getline(skipStr, 256, '\n'))
;
}
// get list now
for (prjf.getline(skipStr, 256, '\n') ; // skip blank lines
prjf && strcmp(skipStr, term) != 0 ;
prjf.getline(skipStr, 256, '\n'))
{
if (*skipStr != ' ')
sl.insert(-1,skipStr); // add to end of list
}
if (!prjf)
return false;
else
return true;
}
//======================>>> makefileMaker::loadProject <<<============================
void makefileMaker::loadProject (char *n)
{
//loads infos contained in project file n into makefileMaker member vars
ifstream prjf(n);
if (!prjf)
return;
eraseAll();
// Project Options
if (!getSectionList(prjf, SecProjOpts, SecProjOptsEnd, projOpts))
return;
// Makefile
if (!getSectionEntry(prjf, SecMakefile, makeName))
return;
//0) options
if (!getSectionList(prjf, SecOptions, SecOptionsEnd, curOpts))
return;
// HOMEV
if (!getSectionEntry(prjf, SecHomeV, homeV))
return;
//1) exe name
if (!getSectionEntry(prjf, SecTarget, exeName))
return;
//2) objs
if (!getSectionList(prjf, SecObjFiles, SecObjFilesEnd, objFiles))
return;
//3) compiler name
if (!getSectionEntry(prjf, SecCompiler, cc))
return;
//4) include dirs
if (!getSectionList(prjf, SecIncDirs, SecIncDirsEnd, incDirs))
return;
//5) lib dirs
if (!getSectionList(prjf, SecLibDirs, SecLibDirsEnd, libDirs))
return;
//6) defs
if (!getSectionList(prjf, SecDefs, SecDefsPoolEnd, defsPool))
return;
if (!getSectionList(prjf, "", SecDefsEnd, curDefs))
return;
//7) cflag
if (!getSectionEntry(prjf, SecCFlags, cFlags))
return;
//8) libflag
if (!getSectionEntry(prjf, SecLibFlags, Libs))
return;
// SRC directory
if (!getSectionEntry(prjf, SecSrcDir, SrcDir))
return;
// 9) object directory
if (!getSectionEntry(prjf, SecObjDir, ObjDir))
return;
//10) bin directory
if (!getSectionEntry(prjf, SecBinDir, BinDir))
return;
// User targets.
if (!getSectionList(prjf, SecUserTargets, SecUserTargetsEnd, userTargets))
return;
}