diff --git a/buildtool.cpp b/buildtool.cpp
index 24de4107707c2b85a5a98f9db964da2a0268e310..21a7a4aef8131d83b30a315530adc850e15a00d8 100644 (file)
--- a/buildtool.cpp
+++ b/buildtool.cpp
*
*/
-#define BUILDTOOL_VERSION "BuildTool v0.7.6, 2007-2008 Bob Jamison"
+#define BUILDTOOL_VERSION "BuildTool v0.8.1, 2007-2008 Bob Jamison"
#include <stdio.h>
#include <fcntl.h>
};
+//########################################################################
+//# F I L E L I S T
+//########################################################################
+/**
+ * This is a simpler, explicitly-named list of files
+ */
+class FileList
+{
+public:
+
+ /**
+ *
+ */
+ FileList()
+ {}
+
+ /**
+ *
+ */
+ FileList(const FileList &other)
+ { assign(other); }
+
+ /**
+ *
+ */
+ FileList &operator=(const FileList &other)
+ { assign(other); return *this; }
+
+ /**
+ *
+ */
+ virtual ~FileList()
+ {}
+
+ /**
+ *
+ */
+ String getDirectory()
+ { return directory; }
+
+ /**
+ *
+ */
+ void setDirectory(const String &val)
+ { directory = val; }
+
+ /**
+ *
+ */
+ void setFiles(const std::vector<String> &val)
+ { files = val; }
+
+ /**
+ *
+ */
+ std::vector<String> getFiles()
+ { return files; }
+
+ /**
+ *
+ */
+ unsigned int size()
+ { return files.size(); }
+
+ /**
+ *
+ */
+ String operator[](int index)
+ { return files[index]; }
+
+ /**
+ *
+ */
+ void clear()
+ {
+ directory = "";
+ files.clear();
+ }
+
+
+private:
+
+ void assign(const FileList &other)
+ {
+ directory = other.directory;
+ files = other.files;
+ }
+
+ String directory;
+ std::vector<String> files;
+};
+
+
//########################################################################
*/
void status(const char *fmt, ...);
+ /**
+ * Show target status
+ */
+ void targetstatus(const char *fmt, ...);
+
/**
* Print a printf()-like formatted trace message
*/
bool parseFileSet(Element *elem,
MakeBase &propRef,
FileSet &fileSet);
+ /**
+ * Parse a <filelist> entry
+ */
+ bool parseFileList(Element *elem,
+ MakeBase &propRef,
+ FileList &fileList);
/**
* Return this object's property list
}
-
/**
* Resolve another path relative to this one
*/
return true;
}
+/**
+ * Parse a <filelist> entry. This is far simpler than FileSet,
+ * since no directory scanning is needed. The file names are listed
+ * explicitly.
+ */
+bool MakeBase::parseFileList(Element *elem,
+ MakeBase &propRef,
+ FileList &fileList)
+{
+ std::vector<String> fnames;
+ //Look for child tags, namely "file"
+ std::vector<Element *> children = elem->getChildren();
+ for (unsigned int i=0 ; i<children.size() ; i++)
+ {
+ Element *child = children[i];
+ String tagName = child->getName();
+ if (tagName == "file")
+ {
+ String fname = child->getAttribute("name");
+ if (fname.size()==0)
+ {
+ error("<file> element requires name="" attribute");
+ return false;
+ }
+ fnames.push_back(fname);
+ }
+ else
+ {
+ error("tag <%s> not allowed in <fileset>", tagName.c_str());
+ return false;
+ }
+ }
+
+ String dir;
+ //Get the base directory for reading file names
+ if (!propRef.getAttribute(elem, "dir", dir))
+ return false;
+ fileList.setDirectory(dir);
+ fileList.setFiles(fnames);
+
+ return true;
+}
+
/**
name = other.name;
}
+ /**
+ * Show task status
+ */
+ void taskstatus(const char *fmt, ...)
+ {
+ va_list args;
+ va_start(args,fmt);
+ fprintf(stdout, " %s : ", name.c_str());
+ vfprintf(stdout, fmt, args);
+ fprintf(stdout, "\n");
+ va_end(args) ;
+ }
+
String getAttribute(Element *elem, const String &attrName)
{
String str;
defines = "";
includes = "";
fileSet.clear();
+ excludeInc.clear();
}
virtual ~TaskCC()
{}
- virtual bool needsCompiling(const FileRec &depRec,
- const String &src, const String &dest)
+ virtual bool isExcludedInc(const String &dirname)
{
+ for (unsigned int i=0 ; i<excludeInc.size() ; i++)
+ {
+ String fname = excludeInc[i];
+ if (fname == dirname)
+ return true;
+ }
return false;
- }
+ }
virtual bool execute()
{
String fullName = parent.resolve("build.dep");
if (isNewerThan(parent.getURI().getPath(), fullName))
{
- status(" : regenerating C/C++ dependency cache");
+ taskstatus("regenerating C/C++ dependency cache");
refreshCache = true;
}
std::set<String>::iterator setIter;
for (setIter=paths.begin() ; setIter!=paths.end() ; setIter++)
{
+ String dirName = *setIter;
+ //check excludeInc to see if we dont want to include this dir
+ if (isExcludedInc(dirName))
+ continue;
incs.append(" -I");
String dname;
if (source.size()>0)
dname.append(source);
dname.append("/");
}
- dname.append(*setIter);
+ dname.append(dirName);
incs.append(parent.resolve(dname));
}
std::vector<String> cfiles;
//# First we check if the source is newer than the .o
if (isNewerThan(srcFullName, destFullName))
{
- status(" : compile of %s required by %s",
+ taskstatus("compile of %s required by source: %s",
destFullName.c_str(), srcFullName.c_str());
compileMe = true;
}
// destFullName.c_str(), depFullName.c_str());
if (depRequires)
{
- status(" : compile of %s required by %s",
+ taskstatus("compile of %s required by included: %s",
destFullName.c_str(), depFullName.c_str());
compileMe = true;
break;
return false;
source = fileSet.getDirectory();
}
+ else if (tagName == "excludeinc")
+ {
+ if (!parseFileList(child, parent, excludeInc))
+ return false;
+ }
}
return true;
protected:
- String ccCommand;
- String cxxCommand;
- String source;
- String dest;
- String flags;
- String defines;
- String includes;
- FileSet fileSet;
+ String ccCommand;
+ String cxxCommand;
+ String source;
+ String dest;
+ String flags;
+ String lastflags;
+ String defines;
+ String includes;
+ FileSet fileSet;
+ FileList excludeInc;
};
{
if (fileName.size()>0)
{
- status(" : %s to %s",
+ taskstatus("%s to %s",
fileName.c_str(), toFileName.c_str());
String fullSource = parent.resolve(fileName);
String fullDest = parent.resolve(toFileName);
}
if (!isNewerThan(fullSource, fullDest))
{
- status(" : skipped");
+ taskstatus("skipped");
return true;
}
if (!copyFile(fullSource, fullDest))
return false;
- status(" : 1 file copied");
+ taskstatus("1 file copied");
}
return true;
}
return false;
String fileSetDir = fileSet.getDirectory();
- status(" : %s to %s",
+ taskstatus("%s to %s",
fileSetDir.c_str(), toDirName.c_str());
int nrFiles = 0;
return false;
nrFiles++;
}
- status(" : %d file(s) copied", nrFiles);
+ taskstatus("%d file(s) copied", nrFiles);
}
else //file source
{
//For file->dir we want only the basename of
//the source appended to the dest dir
- status(" : %s to %s",
+ taskstatus("%s to %s",
fileName.c_str(), toDirName.c_str());
String baseName = fileName;
unsigned int pos = baseName.find_last_of('/');
}
if (!isNewerThan(fullSource, fullDest))
{
- status(" : skipped");
+ taskstatus("skipped");
return true;
}
if (!copyFile(fullSource, fullDest))
return false;
- status(" : 1 file copied");
+ taskstatus("1 file copied");
}
return true;
}
}
case DEL_DIR:
{
- status(" : %s", dirName.c_str());
+ taskstatus("%s", dirName.c_str());
String fullDir = parent.resolve(dirName);
if (!removeDirectory(fullDir))
return false;
public:
TaskJar(MakeBase &par) : Task(par)
- { type = TASK_JAR; name = "jar"; }
+ { type = TASK_JAR; name = "jar"; command = "jar";}
virtual ~TaskJar()
{}
virtual bool execute()
{
+ String cmd = command;
+ cmd.append(" -cf ");
+ cmd.append(destfile);
+ cmd.append(" -C ");
+ cmd.append(basedir);
+ cmd.append(" .");
+
+ String execCmd = cmd;
+
+ String outString, errString;
+ bool ret = executeCommand(execCmd.c_str(), "", outString, errString);
+ if (!ret)
+ {
+ error("<jar> command '%s' failed :\n %s",
+ execCmd.c_str(), errString.c_str());
+ return false;
+ }
return true;
}
virtual bool parse(Element *elem)
{
+ String s;
+ if (!parent.getAttribute(elem, "command", s))
+ return false;
+ if (s.size() > 0)
+ command = s;
+ if (!parent.getAttribute(elem, "basedir", basedir))
+ return false;
+ if (!parent.getAttribute(elem, "destfile", destfile))
+ return false;
+ if (basedir.size() == 0 || destfile.size() == 0)
+ {
+ error("<jar> required both basedir and destfile attributes to be set");
+ return false;
+ }
return true;
}
+
+private:
+ String command;
+ String basedir;
+ String destfile;
};
fclose(f);
if (!count)
{
- status(" : nothing to do");
+ taskstatus("nothing to do");
return true;
}
- status(" : compiling %d files", count);
+ taskstatus("compiling %d files", count);
String execCmd = cmd;
execCmd.append("@");
virtual bool execute()
{
- status(" : %s", fileName.c_str());
+ taskstatus("%s", fileName.c_str());
String fullName = parent.resolve(fileName);
if (!isNewerThan(parent.getURI().getPath(), fullName))
{
virtual bool execute()
{
- status(" : %s", dirName.c_str());
+ taskstatus("%s", dirName.c_str());
String fullDir = parent.resolve(dirName);
//trace("fullDir:%s", fullDir.c_str());
if (!createDirectory(fullDir))
}
}
- status(" : %s", ret.c_str());
+ taskstatus("%s", ret.c_str());
parent.setProperty(propName, ret);
return true;
}
}
}
- status("## Target : %s : %s", name.c_str(),
+ status("##### Target : %s\n##### %s", name.c_str(),
target.getDescription().c_str());
//Now let's do the tasks
for (unsigned int i=0 ; i<tasks.size() ; i++)
{
Task *task = tasks[i];
- status("---- task : %s", task->getName().c_str());
+ status("--- %s / %s", name.c_str(), task->getName().c_str());
if (!task->execute())
{
return false;