From 46a3cfdd7b2a77a308a6ac3fbca3b675c4f44fe7 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 1 Aug 2006 06:27:43 +0000 Subject: It builds fine, and can build other things as well, like squirrelmud, and clean. I need to fix the dependancy tracking so that it will only check if it needs to, sort of like pymake. And does each file as it gets to it. --- build.conf | 7 +++--- src/build.l | 1 + src/build.y | 5 +++++ src/builder.h | 4 +++- src/filetarget.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/filetarget.h | 9 +++++++- src/main.cpp | 7 ++++-- src/perform.cpp | 1 + src/perform.h | 1 + src/performcmd.cpp | 2 +- src/rule.cpp | 11 ++++++++++ 11 files changed, 100 insertions(+), 11 deletions(-) diff --git a/build.conf b/build.conf index 1d7c6a2..b24d7d0 100644 --- a/build.conf +++ b/build.conf @@ -1,14 +1,13 @@ # This is a build file for build default action: check build +"clean" action: clean build create file build from files in src using rule exe set CXXFLAGS += "-Ilibbu++/src" set LDFLAGS += "-Llibbu++ -lbu++" -for build set LDFLAGS += -lreadline - build requires src/libbu++/libbu++.a /(.*)\.o$/ requires from command "g++ {CXXFLAGS} -M {re:1}.c*" @@ -19,8 +18,8 @@ rule exe matches all /(.*)\.o$/ perform command ... rule cpp matches one /(.*)\.c(pp)?$/ produces "{re:1}.o" perform command ... "g++ {CXXFLAGS} -c -o {target} {match}" -rule bison matches one /(.*)\.y$/ produces "{re:1}.tab.c", "{re:1}.tab.h" ... - perform command "bison -v -b{re:1} {match}" +rule bison matches one /(.*)\.y$/ produces "{re:1}.tab.c", "{re:1}.tab.h", ... + "{re:1}.output" perform command "bison -v -b{re:1} {match}" rule flex matches one /(.*)\.l$/ produces "{re:1}.yy.c" perform ... command "flex --bison-bridge --bison-locations -o {target} {match}" diff --git a/src/build.l b/src/build.l index a88f90d..a18cbeb 100644 --- a/src/build.l +++ b/src/build.l @@ -40,6 +40,7 @@ std::string strbuf; "produces" return TOK_PRODUCES; "command" return TOK_COMMAND; "check" return TOK_CHECK; +"clean" return TOK_CLEAN; "..."\n /* elipsis line continuation */ \n+ return TOK_EOL; diff --git a/src/build.y b/src/build.y index ecc5d59..4d87a86 100644 --- a/src/build.y +++ b/src/build.y @@ -49,6 +49,7 @@ void yyerror( YYLTYPE *locp, Builder &bld, char const *msg ); %token TOK_PRODUCES "produces" %token TOK_COMMAND "command" %token TOK_CHECK "check" +%token TOK_CLEAN "clean" %token TOK_EOL "end of line" %token ',' ':' '=' @@ -162,6 +163,10 @@ action: TOK_CHECK STRING { bld.add( new Command( Command::cmdCheck, $2 ) ); } + | TOK_CLEAN STRING + { + bld.add( new Command( Command::cmdClean, $2 ) ); + } ; setexpr: STRING '=' STRING diff --git a/src/builder.h b/src/builder.h index f21e411..f27a042 100644 --- a/src/builder.h +++ b/src/builder.h @@ -100,8 +100,10 @@ public: return mTarget[sName]; } - std::list getRequires( const char *sReq ) + std::list *getRequires( const char *sReq ) { + if( mRequires.find(sReq) == mRequires.end() ) + return NULL; return mRequires[sReq]; } diff --git a/src/filetarget.cpp b/src/filetarget.cpp index 1880c35..f9367a4 100644 --- a/src/filetarget.cpp +++ b/src/filetarget.cpp @@ -1,6 +1,7 @@ #include #include +#include "perform.h" #include "rule.h" #include "filetarget.h" #include "builder.h" // for BuildException @@ -66,8 +67,11 @@ void FileTarget::addInputDir( const char *sDir ) closedir( dir ); } +int nNew, nCache; + void FileTarget::check( Builder &bld ) { + nNew = nCache = 0; Rule *pRule = bld.getRule( sRule ); std::list perf; @@ -79,12 +83,67 @@ void FileTarget::check( Builder &bld ) for( std::list::iterator i = perf.begin(); i != perf.end(); i++ ) { - std::list lReqs = bld.getRequires( (*i)->getTarget() ); - + time_t target = getTime( std::string((*i)->getTarget()) ); + std::list *lReqs = bld.getRequires( (*i)->getTarget() ); + if( lReqs == NULL ) + { + printf("No dependancies: %s\n", (*i)->getTarget() ); + continue; + } + for( std::list::iterator j = lReqs->begin(); + j != lReqs->end(); j++ ) + { + if( getTime( *j ) > target ) + { + (*i)->execute( bld ); + updateTime( (*i)->getTarget() ); + break; + } + } } + + printf("Cache hits %d, %d new (%f%%)\n", nCache, nNew, nCache/ (double)(nNew+nCache)*100.0 ); } void FileTarget::clean( Builder &bld ) { + Rule *pRule = bld.getRule( sRule ); + + std::list perf; + std::list tmp = pRule->execute( bld, lInput, perf, getName() ); + lOutput.insert( lOutput.end(), tmp.begin(), tmp.end() ); + + for( std::list::iterator i = lOutput.begin(); + i != lOutput.end(); i++ ) + { + unlink( (*i).c_str() ); + } +} + +time_t FileTarget::getTime( std::string str ) +{ + std::map::iterator i = mTimes.find( str ); + if( i != mTimes.end() ) + { + nCache++; + return (*i).second; + } + + struct stat st; + stat( str.c_str(), &st ); + + mTimes[str] = st.st_mtime; + + nNew++; + + return st.st_mtime; +} + +void FileTarget::updateTime( std::string str ) +{ + struct stat st; + stat( str.c_str(), &st ); + + mTimes[str] = st.st_mtime; } diff --git a/src/filetarget.h b/src/filetarget.h index c872c0a..856e854 100644 --- a/src/filetarget.h +++ b/src/filetarget.h @@ -2,6 +2,10 @@ #define FILE_TARGET_H #include +#include +#include +#include +#include #include "target.h" class FileTarget : public Target @@ -16,9 +20,12 @@ public: virtual void check( class Builder &bld ); virtual void clean( class Builder &bld ); + + time_t getTime( std::string str ); + void updateTime( std::string str ); private: - // start here with the file time cache + std::map mTimes; }; diff --git a/src/main.cpp b/src/main.cpp index ebf0cfd..ebfb745 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,15 @@ #include "builder.h" -int main() +int main( int argc, char *argv[] ) { Builder bld; bld.load("build.conf"); - bld.build(); + if( argc >= 2 ) + bld.build( argv[1] ); + else + bld.build(); /* printf("\n\n----------\nDebug dump\n----------\n"); bld.debug();*/ diff --git a/src/perform.cpp b/src/perform.cpp index d7082a0..c96d70f 100644 --- a/src/perform.cpp +++ b/src/perform.cpp @@ -8,3 +8,4 @@ Perform::Perform( const char *sTarget ) : Perform::~Perform() { } + diff --git a/src/perform.h b/src/perform.h index 2eb8cb0..914f3b0 100644 --- a/src/perform.h +++ b/src/perform.h @@ -2,6 +2,7 @@ #define PERFORM_H #include +#include "staticstring.h" class Perform { diff --git a/src/performcmd.cpp b/src/performcmd.cpp index 724f42b..d9b7977 100644 --- a/src/performcmd.cpp +++ b/src/performcmd.cpp @@ -3,7 +3,7 @@ PerformCmd::PerformCmd( const char *sCmd, const char *sTarget ) : Perform( sTarget ), - sCommand( sCmd ), + sCommand( sCmd ) { } diff --git a/src/rule.cpp b/src/rule.cpp index 979075b..ce37e93 100644 --- a/src/rule.cpp +++ b/src/rule.cpp @@ -77,6 +77,7 @@ Perform *Rule::buildCommand( Builder &bld, const char *sCmd, Builder::varmap *va std::list Rule::execute( Builder &bld, std::list lInput, std::list &lPerf, const char *sTarget ) { + bld.requiresRegexp( false ); std::list lRule = bld.findRuleChain( this ); /* if( !lRule.empty() ) @@ -134,11 +135,21 @@ std::list Rule::execute( Builder &bld, std::list lInpu revars ); lPerf.push_back( p ); + + bld.requires( + (*revars)["target"].c_str(), + (*revars)["match"].c_str() + ); } else if( mHow == matchAll ) { sMatches += " "; sMatches += (*i); + + bld.requires( + sTarget, + (*i).c_str() + ); } } delete revars; -- cgit v1.2.3